Changeset 3052 for trunk


Ignore:
Timestamp:
10/06/10 16:15:21 (9 years ago)
Author:
jukka
Message:

Removed some of the unused templates, community and portfolio related pages are still there. All kinds of work done towards LeMill 3.

Location:
trunk
Files:
12 added
18 deleted
49 edited
1 moved

Legend:

Unmodified
Added
Removed
  • trunk/ConfigurationMethods.py

    r3014 r3052  
    325325 
    326326 
    327  
    328327def setupTopics(self, portal): 
    329     """Setup pre-defined searches inside SECTIONS to provide a browsable lists of contents.""" 
    330  
    331     portal_types=getToolByName(portal, 'portal_types') 
    332     if hasattr(portal_types, 'Topic'): 
    333         methodlist=portal_types.Topic.getAvailableViewMethods(None) 
    334         if DEFAULT_TOPIC_VIEW not in methodlist: 
    335             methodlist=methodlist+(DEFAULT_TOPIC_VIEW,) 
    336         portal_types.Topic.manage_changeProperties(view_methods=methodlist) 
    337         portal_types.Topic.manage_changeProperties(default_view=DEFAULT_TOPIC_VIEW) 
    338  
    339     syn_tool = getToolByName(portal, 'portal_syndication') 
    340     # Loop through all main sections 
    341     for foldername in SECTIONS.keys(): 
    342         if SECTION_TOPICS.has_key(foldername): 
    343             # additional loop for having several kinds of type restrictions 
    344             for topic_type in SECTION_TOPICS[foldername]: 
    345                 generated_topics = topic_type[1] 
    346                 allowed_types = topic_type[0] 
    347                 # Loop through topics inside folders 
    348                 if SECTION_TOPICS[foldername]: 
    349                     folder = getattr(portal, foldername.lower()) 
    350                     for topic_conf in generated_topics: 
    351                         # Create topics with specific queries 
    352                         if hasattr(folder.aq_base, topic_conf['id']): 
    353                             folder._delObject(topic_conf['id']) 
    354                         addObject(folder, topic_conf['id'], 'Topic', topic_conf['title']) 
    355                         # Set up properties for topics 
    356                         topic = getattr(folder, topic_conf['id']) 
    357                         topic.manage_permission(ADD_CONTENT_PERMISSION, ('Member',), acquire=1)  
    358                         topic.manage_permission(LIST_FOLDER_CONTENTS, ('Member',), acquire=1) 
    359                         sortby='getScore' 
    360                         if topic_conf.has_key('sortby'): 
    361                             sortby=topic_conf['sortby'] 
    362                         rev = False 
    363                         if topic_conf.has_key('reversed'): 
    364                             rev=topic_conf['reversed'] 
    365                         topic.setSortCriterion(sortby, reversed=rev) 
    366                         getmethod='sortable_title' 
    367                         if topic_conf.has_key('getmethod'): 
    368                             getmethod=topic_conf['getmethod'] 
    369                         topic.getmethod=getmethod 
    370                         if allowed_types: 
    371                             criterion = topic.addCriterion('Type', 'ATPortalTypeCriterion' ) 
    372                             criterion.setValue(allowed_types) 
    373                         # Set additional criterions for drafts and publisheds 
    374                         if topic_conf.has_key('criterions'): 
    375                             for crit,crittype,value in topic_conf['criterions']: 
    376                                 criterion = topic.addCriterion(crittype, crit) 
    377                                 if not value=='': 
    378                                     criterion.setValue(value) 
    379                         else: 
    380                             criterion = topic.addCriterion('getState','ATSelectionCriterion') 
    381                             criterion.setValue(('public','draft'))     
    382                         if topic_conf['id'] == 'recent': 
    383                             crit = topic.addCriterion('getLatestEdit', 'ATFriendlyDateCriteria') 
    384                             crit.setOperation('less') 
    385                             crit.setDateRange('-') 
    386                             crit.setValue('3') 
    387                         if topic_conf['id'] == 'portfolio': 
    388                             if not hasattr(topic.aq_base, 'left_slots'): 
    389                                 topic._setProperty('left_slots', ['here/portlet_portfolio/macros/backlinks',], 'lines') 
    390                         if topic_conf.has_key('view'): 
    391                             topic.setLayout(topic_conf['view']) 
    392                         # disabling syndication for drafts and published folders 
    393                         if topic_conf['id'] in ['drafts', 'published']: 
    394                             try: 
    395                                 syn_tool.disableSyndication(topic) 
    396                             except AttributeError: 
    397                                 pass 
     328    """ From v 3.0-> we don't use topics anymore. This method makes sure they are removed. :/ """ 
     329    removed_topics = { 
     330        'content': ['tags','published','browse_resources','drafts','language','subject_area','target_group','browse_references','browse_pieces','recent'], 
     331        'methods': ['language','tags','published','browse_methods'], 
     332        'tools': ['language','tags','published','browse_tools'] 
     333    } # Community is still kept 
     334    #        'Community': 
     335    #        # *********************** 
     336    #        [(CONTENT_TYPES + ACTIVITY_TYPES + TOOLS_TYPES+('GroupBlog',),( 
     337    #        {'id':'portfolio', 'title':'Portfolio', 'getmethod':'getTags', 'sortby':'getLatestEdit', 'reversed':True, 'view':'lemill_portfolio_view'},)), 
     338    #        # +++++++++++++++++++++++ 
     339    #        (('MemberFolder',),( 
     340    #        {'id':'browse_people', 'title':'Members', 'getmethod':'sortable_title', 'view':'lemill_titlecloud'}, 
     341    #        {'id':'language', 'title':'Language', 'getmethod':'getLanguage_skills', 'view':'lemill_browse_members'}, 
     342    #        {'id':'country', 'title':'Location', 'getmethod':'getLocation_country', 'view':'lemill_browse_members'}, 
     343    #        {'id':'skills', 'title':'Skills', 'getmethod':'getSkills', 'view':'lemill_browse_members'}, 
     344    #        {'id':'interests', 'title':'Interests',  'getmethod':'getInterests', 'view':'lemill_browse_members'}, 
     345    #        {'id':'subject_area', 'title':'Subject area', 'getmethod':'getSubject_area', 'view':'lemill_browse_members'})), 
     346    #        # +++++++++++++++++++++++ 
     347    #        (('GroupBlog',),( 
     348    #        {'id':'browse_groups', 'title':'Groups', 'view':'lemill_titlecloud'}, 
     349    #        {'id':'tags', 'title':'Tags', 'getmethod':'getTags','view':'lemill_browse_groups'}, 
     350    #        {'id':'g_language', 'title':'Language', 'getmethod':'getLanguage_skills', 'view':'lemill_browse_groups'}, 
     351    #        {'id':'group_subject_area', 'title':'Subject area', 'getmethod':'getSubject_area', 'view':'lemill_browse_groups'})) 
     352    #        # +++++++++++++++++++++++ 
     353    #        ]}         
     354    for section,topic_ids in removed_topics.items(): 
     355        section=getattr(portal, section) 
     356        del_ids=[] 
     357        for topic_id in topic_ids: 
     358            topic= getattr(section, topic_id, None) 
     359            if topic and getattr(topic, 'meta_type','') == 'ATTopic': 
     360                del_ids.append(topic_id) 
     361        if del_ids: 
     362            print 'deleting obsolete topics:', del_ids 
     363            section.manage_delObjects(del_ids) 
     364     
    398365 
    399366def setupRemoteLeMills(self, portal): 
     
    496463    if not hasattr(lt, 'irc_link'): 
    497464        safeEditProperty(lt, 'irc_link', value='http://neumann.uiah.fi/irc/irc.cgi', data_type="string") 
    498     lt.language_dict=dict(portal.availableLanguages()) 
     465    lt.language_dict=dict(LANGUAGES) 
    499466    safeEditProperty(portal, 'validate_email', value=False, data_type="boolean") 
    500467     
  • trunk/GroupBlog.py

    r3027 r3052  
    2828from Products.CMFPlone.PloneBatch import Batch 
    2929 
    30 from config import PROJECTNAME, MODIFY_CONTENT, VIEW, DEFAULT_ICONS, MATERIAL_TYPES, to_unicode 
     30from config import PROJECTNAME, MODIFY_CONTENT, VIEW, DEFAULT_ICONS, MATERIAL_TYPES, to_unicode, LANGUAGES 
    3131from permissions import MODIFY_CONTENT 
    3232from Schemata import tags, coverImage, deletionReason, score, subject_area_schema, latest_edit_schema, state 
     
    253253 
    254254    def getLanguagelist(self): 
    255         languagelist=self.availableLanguages() 
    256         return DisplayList(languagelist)  
     255        return DisplayList(LANGUAGES)  
    257256 
    258257    def canIEdit(self, member=None): 
  • trunk/LargeSectionFolder.py

    r3045 r3052  
    584584            results=results[:30] 
    585585            shuffle(results) 
    586             if len(results)>2: 
    587                 return results[:3] 
     586            if len(results)>3: 
     587                return results[:4] 
    588588            else: 
    589589                good_results+=results 
    590             if len(good_results)>2: 
    591                 return good_results[:3] 
     590            if len(good_results)>3: 
     591                return good_results[:4] 
    592592        return good_results 
    593593 
     
    640640        topthree= [(n,key) for key, n in res.items() if n>1 and key]         
    641641        topthree.sort(reverse=True) 
    642         topthree=[key for n,key in topthree[:3]] 
     642        topthree=[key for n,key in topthree[:5]] 
    643643        return topthree 
    644  
    645     ##############################      Clouds      ########################   
    646  
    647     def getTitleCloud(self, search_results, browse_type): 
    648         """ Build a cloud based on popularity score for that resource """ 
    649         pc=getToolByName(self,'portal_catalog') 
    650         # uniquetuplelist contains result metadata reordered: (sort_title, count, url, indexvalue, title) 
    651         from math import log 
    652         if not search_results: 
    653             return [] 
    654  
    655         def adjust(i): 
    656             # helper method to adjust hit count of this tag to relative size (1,...,8)  
    657             (a,b,c,d,e)=i 
    658             b=int((8*log(b,2))/log(maxscore,2)) 
    659             if b==0: 
    660                 b=1 
    661             i=(a,b,c,d,e) 
    662             return i         
    663         def isDefaultTitle(x): 
    664             """ some heuristic to recognize default titles """ 
    665             return re.match(r'.*\.(...)$', x) or re.match(r'.*\.(....)$', x)  
    666                      
    667         popularity = pc.fastMetadata(search_results, ('getScore','rid','getNicename','sortable_title')) 
    668         popularity.sort(reverse=True) 
    669         popularity=popularity[:100] 
    670         titlecloud=[(sortable_title, getScore, self.REQUEST.physicalPathToURL(pc.getpath(rid)), sortable_title, getNicename or sortable_title) for (getScore, rid, getNicename, sortable_title) in popularity if sortable_title] 
    671          
    672         if not titlecloud: 
    673             return [] 
    674         titlecloud.sort() 
    675         maxscore=max([x[1] for x in titlecloud]) 
    676         if maxscore>1: 
    677             titlecloud=map(adjust, titlecloud) 
    678         return titlecloud 
    679  
    680     def getTagCloud(self, search_results, index_type): 
    681         """ Build a cloud based on how many occurences of this item are in results """ 
    682         if not search_results: 
    683             return [] 
    684         lemill_tool = getToolByName(self, 'lemill_tool') 
    685         pc = getToolByName(self, 'portal_catalog') 
    686         from math import log 
    687         maxcount=0 
    688  
    689         def adjust(i): 
    690             # helper method to adjust hit count of this tag to relative size (1,...,8)  
    691             (a,b,c,d,e)=i 
    692             try: 
    693                 b=int((8*log(b-mincount,2))/log(maxcount-mincount,2)) 
    694             except (OverflowError, ZeroDivisionError): 
    695                 b=0 
    696             if b==0: 
    697                 b=1 
    698             i=(a,b,c,d,e) 
    699             return i 
    700         hits={} 
    701         hits=pc.fastCount(search_results, index_type) 
    702         resultlist=zip(hits.values(),hits.keys()) 
    703         if not resultlist: 
    704             return [] 
    705         resultlist.sort() 
    706         resultlist.reverse() 
    707         maxcount=resultlist[0][0] # first! 
    708         # if the first cut score for tag is x, we want to cut off all of the tags with score x.  
    709         if len(resultlist)>100: 
    710             #cutpoint = [x[0] for x in resultlist].index(resultlist[100]) can't figure this now, fix later 
    711             cutpoint = 100 
    712             resultlist = resultlist[:cutpoint] 
    713         mincount=resultlist[-1][0] 
    714         resultlist=[(x[1], x[0], '',x[1],x[1]) for x in resultlist] 
    715  
    716         # adjust to 1-8. We don't have to worry about score 0, they're already removed. 
    717         if maxcount>1: 
    718             resultlist=map(adjust, resultlist) 
    719         # prettify language names 
    720         if index_type=='Language' or index_type=='getLanguage_skills': 
    721             resultlist=[(x[0],x[1],x[2],x[3],lemill_tool.getPrettyLanguage(x[4])) for x in resultlist]             
    722         if index_type=='getTarget_group': 
    723             def compfunc(t2,t1): 
    724                 if t2[0] in TARGET_GROUP and t1[0] in TARGET_GROUP: 
    725                     return  TARGET_GROUP.index(t2[0]) - TARGET_GROUP.index(t1[0]) 
    726                 else: 
    727                     return -1 
    728             resultlist.sort(cmp=compfunc) 
    729         else:     
    730             resultlist.sort() 
    731         return resultlist 
    732644 
    733645 
     
    795707        return result   
    796708 
     709    def getLanguageFilter(self): 
     710        """ returns 'language=xx&' or '' if there is a language cookie set """ 
     711        ilanguage=getToolByName(self, 'portal_languages').getLanguageCookie() 
     712        if ilanguage: 
     713            return 'language=%s&' % ilanguage  
     714        else: 
     715            return '' 
     716 
    797717 
    798718    ################# RSS ###################################### 
     
    829749        return self._getSamples(MATERIAL_TYPES) 
    830750 
    831     def getSelectables(self, results): 
    832         """takes search results as input and returns a dictionary that tells what values there are available for each selection box and how many results there are of each value.""" 
    833         pc=getToolByName(self, 'portal_catalog') 
    834         lang_dict = getToolByName(self, 'lemill_tool').language_dict 
    835         if len(results)<101: 
    836             langs, targs, types, subjs, tags = pc.fastCount(results, ('Language','getTarget_group','portal_type','getSubject_area','getTags')) 
    837         else: 
    838             langs, targs, types, subjs= pc.fastCount(results, ('Language','getTarget_group','portal_type','getSubject_area')) 
    839             tags={} 
    840         # Convert them to tuples where (value, display value) 
    841         langlist=zip(map(lambda x: lang_dict[x], langs.keys()), langs.keys(),langs.values()) 
    842         targlist=zip(targs.keys(),targs.keys(),targs.values()) 
    843         typelist=zip(map(lambda x: TYPE_NAMES[x][0], types.keys()), types.keys(), types.values()) 
    844         subjslist=zip(subjs.keys(),subjs.keys(),subjs.values()) 
    845         tagslist=zip(tags.keys(),tags.keys(),tags.values()) 
    846         langlist.sort() 
    847         targlist.sort() 
    848         typelist.sort() 
    849         subjslist.sort() 
    850         tagslist.sort() 
    851         return {'language':langlist, 'target_group':targlist, 'type':typelist, 'subject_area':subjslist, 'tag':tagslist, 'drafts':[('Show drafts', 'no', 0)]} 
    852          
    853     def hasBrowseArguments(self, source): 
    854         """ Checks if we should browse or show tagcloud """ 
    855         goodargs=['language','target_group','tag','type','subject_area','drafts'] 
    856         for (key, value) in source.items(): 
    857             if key in goodargs and value: 
    858                 return True 
    859         return False 
    860  
    861751    def getTemplate(self, template_id): 
    862752        return TEMPLATES.get(template_id, None) 
    863  
    864753 
    865754    security.declareProtected(ADD_CONTENT_PERMISSION,'lemidlet_post') 
     
    891780        """ Returns 3 methods/activities """ 
    892781        return self._getSamples('Activity') 
    893  
    894     def hasBrowseArguments(self, source): 
    895         """ Checks if we should browse or show tagcloud """ 
    896         goodargs=['language','tag'] 
    897         for (key, value) in source.items(): 
    898             if key in goodargs and value: 
    899                 return True 
    900         return False 
    901  
    902     def getSelectables(self, results): 
    903         """Try to find which of languages and tags are found in results""" 
    904         pc=getToolByName(self, 'portal_catalog') 
    905         lang_dict = getToolByName(self, 'lemill_tool').language_dict 
    906         langs, tags = pc.fastCount(results, ('Language','getTags')) 
    907         # Convert them to tuples where (value, display value) 
    908         langlist=zip(map(lambda x: lang_dict[x], langs.keys()), langs.keys(),langs.values()) 
    909         tagslist=zip(tags.keys(),tags.keys(),tags.values()) 
    910         langlist.sort() 
    911         tagslist.sort() 
    912         return {'language':langlist,'tag':tagslist} 
    913782     
    914783class LargeToolFolder(LargeSectionFolder): 
     
    926795        """ Returns 3 tools """ 
    927796        return self._getSamples('Tool') 
    928  
    929  
    930     def hasBrowseArguments(self, source): 
    931         """ Checks if we should browse or show tagcloud """ 
    932         goodargs=['language','tag'] 
    933         for (key, value) in source.items(): 
    934             if key in goodargs and value: 
    935                 return True 
    936         return False 
    937  
    938     def getSelectables(self, results): 
    939         """Try to find which of languages and tags are found in results""" 
    940         pc=getToolByName(self, 'portal_catalog') 
    941         lang_dict = getToolByName(self, 'lemill_tool').language_dict 
    942         langs, tags = pc.fastCount(results, ('Language','getTags')) 
    943         # Convert them to tuples where (value, display value) 
    944         langlist=zip(map(lambda x: lang_dict[x], langs.keys()), langs.keys(),langs.values()) 
    945         tagslist=zip(tags.keys(),tags.keys(),tags.values()) 
    946         langlist.sort() 
    947         tagslist.sort() 
    948         return {'language':langlist,'tag':tagslist} 
    949  
    950797 
    951798class LargeCommunityFolder(LargeSectionFolder): 
     
    998845 
    999846    def getSamples(self): 
    1000         """ Get 3 random members or groups """   
     847        """ Get 4 random groups """   
    1001848        lutool=getToolByName(self, 'lemill_usertool') 
    1002849        lt=getToolByName(self,'lemill_tool') 
     
    1006853        while languages: 
    1007854            lang=languages.pop(0) 
    1008             results=pc(portal_type=['MemberFolder','GroupBlog'], getLanguage_skills=lang, getState='public', getHasCoverImage=True, sort_on='getScore', sort_order='descending') 
     855            results=pc(portal_type='GroupBlog', getLanguage_skills=lang, getState='public', getHasCoverImage=True, sort_on='getScore', sort_order='descending') 
    1009856            results=results[:30] 
    1010857            shuffle(results) 
    1011             if len(results)>2: 
    1012                 return results[:3] 
     858            if len(results)>3: 
     859                return results[:4] 
    1013860            else: 
    1014861                good_results+=results 
    1015             if len(good_results)>2: 
    1016                 return good_results[:3] 
     862            if len(good_results)>3: 
     863                return good_results[:4] 
    1017864        return good_results 
    1018865         
     
    1044891        return res 
    1045892 
    1046  
    1047     def getSelectablesForMembers(self, results): 
    1048         """Try to find which of languages and target groups are selectable""" 
    1049         pc=getToolByName(self, 'portal_catalog') 
    1050         langs, subjs, locas, skills, interests = pc.fastCount(results, ('getLanguage_skills','getSubject_area','getLocation_country','getSkills','getInterests')) 
    1051         lang_dict = getToolByName(self, 'lemill_tool').language_dict 
    1052         if langs.has_key('No country specified'): 
    1053             del langs['No country specified'] 
    1054         # Convert them to tuples where (value, display value) 
    1055         langlist=zip(map(lambda x: lang_dict[x], langs.keys()), langs.keys(),langs.values()) 
    1056         subjslist=zip(subjs.keys(),subjs.keys(),subjs.values()) 
    1057         locaslist=zip(locas.keys(),locas.keys(),locas.values()) 
    1058         skillslist=zip(skills.keys(),skills.keys(),skills.values()) 
    1059         interestslist=zip(interests.keys(),interests.keys(),interests.values()) 
    1060         langlist.sort() 
    1061         subjslist.sort() 
    1062         locaslist.sort() 
    1063         skillslist.sort() 
    1064         interestslist.sort() 
    1065         return {'language_skills':langlist, 'subject_area':subjslist, 'location':locaslist,'skills':skillslist,'interests':interestslist} 
    1066          
    1067     def hasBrowseArguments(self, source): 
    1068         """ Checks if we should browse or show tagcloud """ 
    1069         goodargs=['type','language_skills','skills','interests','location','subject_area','tag','subject_area'] 
    1070         for key in source.keys(): 
    1071             if key in goodargs and source[key]: 
    1072                 return True 
    1073         return False 
    1074  
    1075     def getSelectablesForGroups(self, results): 
    1076         """Try to find which of languages are found in results""" 
    1077         pc=getToolByName(self, 'portal_catalog') 
    1078         langs, subjs, tags = pc.fastCount(results, ('getLanguage_skills','getSubject_area','getTags')) 
    1079  
    1080         lang_dict = getToolByName(self, 'lemill_tool').language_dict 
    1081         # Convert them to tuples where (value, display value) 
    1082         langlist=zip(map(lambda x: lang_dict[x], langs.keys()), langs.keys(),langs.values()) 
    1083         subjslist=zip(subjs.keys(),subjs.keys(),subjs.values()) 
    1084         tagslist=zip(tags.keys(),tags.keys(),tags.values()) 
    1085         langlist.sort() 
    1086         subjslist.sort() 
    1087         tagslist.sort() 
    1088         return {'language_skills':langlist, 'group_subject_area':subjslist,'tag':tagslist} 
    1089  
    1090893    def getCreatorstring(self, source): 
    1091894        """ return string to attach to url to limit results for one person or group """ 
  • trunk/LeMillCatalogTool.py

    r3002 r3052  
    1010from Products.ZCatalog.ZCatalog import ZCatalog 
    1111from Products.CMFPlone.CatalogTool import CatalogTool as PloneCatalogTool 
     12from Products.CMFPlone.PloneBatch import Batch 
     13from Products.PythonScripts.standard import urlencode 
    1214 
    1315from zope.interface import implements 
    1416 
    15 from Products.CMFCore.utils import SimpleRecord 
     17from Products.CMFCore.utils import SimpleRecord, getToolByName 
    1618from Products.ZCTextIndex.HTMLSplitter import HTMLWordSplitter 
    1719from Products.ZCTextIndex.Lexicon import CaseNormalizer 
     
    2325from Products.ZCTextIndex.ZCTextIndex import PLexicon 
    2426from Products.ZCatalog.Lazy import Lazy 
     27from random import randint 
     28from config import CONTENT_TYPES, MATERIAL_TYPES, ACTIVITY_TYPES, TOOLS_TYPES, LANGUAGES, LANGUAGES_DICT, TYPE_NAMES, SUBJECT_AREAS_DICT, TARGET_GROUPS_DICT, SUBJECT_AREAS_INVERSE_DICT, TARGET_GROUPS_INVERSE_DICT, COMMUNITY_TYPES, SEARCHABLE_TYPES, DEFAULT_ICONS, TARGET_GROUP 
    2529import time 
     30from math import log 
    2631 
    2732class CatalogTool(PloneCatalogTool): 
     
    104109    __call__ = searchResults 
    105110 
     111 
     112    def titleSearch(self, title='', sort_limit=0): 
     113        """ search titles containing given string """ 
     114        query={'getState':('draft', 'public'), 'sort_on':'getScore', 'sort_order':'reverse'} 
     115        if sort_limit: 
     116            query['sort_limit']=sort_limit 
     117        query['Title']='%s*' % title 
     118        results=self.searchResults(query) 
     119        return results 
     120 
     121    def fulltextSearch(self, SearchableText='', sort_limit=0): 
     122        """ search fulltext for a string """ 
     123        query={'getState':('draft', 'public'), 'sort_on':'getScore', 'sort_order':'reverse'} 
     124        if sort_limit: 
     125            query['sort_limit']=sort_limit 
     126        query['SearchableText']='%s*' % SearchableText 
     127        results=self.searchResults(query) 
     128        return results 
     129 
     130    def buildResultsFromBatch(self, batch): 
     131        t=time.time() 
     132        d_list=[] 
     133        lutool=getToolByName(self, 'lemill_usertool') 
     134        url_base=getToolByName(self, 'portal_url')() 
     135 
     136        if hasattr(batch._sequence, '_seq'): 
     137            print 'using fast metadata to build results' 
     138            seq=list(batch._sequence._seq[batch.start:batch.end]) 
     139            print time.time()-t 
     140            md=self.fastMetadata(seq, ['rid','getHasCoverImage','getNicename','portal_type','getLocation_country','getTags', 'Language','listCreators']) 
     141            print time.time()-t 
     142            for item in md: 
     143                if item[3] not in TYPE_NAMES: 
     144                    print 'rejected item:', item  
     145                    continue 
     146                d={'url':self.getpath(item[0]), 
     147                    'coverimage_url':item[1], 
     148                    'title':item[2], 
     149                    'readable_type':item[3], 
     150                    'country':item[4], 
     151                    'tags':item[5], 
     152                    'language':item[6], 
     153                    'authors':item[7]} 
     154                d_list.append(d) 
     155        else: # batch has already been converted to catalog Brains object 
     156            print 'using Brains objects to build results' 
     157            for item in batch:                 
     158                d={'url':item.getURL(), 
     159                    'coverimage_url':item.getHasCoverImage, 
     160                    'title':item.getNicename, 
     161                    'readable_type':item.portal_type, 
     162                    'country':item.getLocation_country, 
     163                    'tags':item.getTags, 
     164                    'language':item.Language, 
     165                    'authors':item.listCreators}                   
     166                d_list.append(d) 
     167        tag_base='/'.join((url_base,'search?index_type=tags&q=')) 
     168        lang_base='/'.join((url_base,'search?language=')) 
     169        country_base='/'.join((url_base,'community/browse?country=')) 
     170        # Manipulate raw index data to something more useful 
     171        for item in d_list: 
     172            if callable(item['title']): 
     173                item['title']=item['title']() 
     174            url=item['url'] 
     175            if item['coverimage_url']: 
     176                item['coverimage_url']='/'.join((url,'coverImage')) 
     177            else: 
     178                item['coverimage_url']='/'.join((url_base, DEFAULT_ICONS[item['readable_type']])) 
     179            ll=item['language'] 
     180            if ll: 
     181                item['language']=LANGUAGES_DICT[ll] 
     182                item['language_link']=''.join((lang_base,ll)) 
     183            item['tags']=[(tag, ''.join((tag_base, tag))) for tag in item['tags']] 
     184            item['authors']=[self.fastLink(author) for author in item['authors']] 
     185            if item['country']:          
     186                item['country_link']=''.join((country_base,item['country'])) 
     187            item['readable_type']=TYPE_NAMES.get(item['readable_type'], None)[0] 
     188 
     189        print 'result batch creation took: ',time.time()-t 
     190        return d_list 
     191 
     192 
     193    def createBrowsingOptions(self, REQUEST, results=None): 
     194        """takes search results as input and returns a dictionary that tells what values there are available for each selection box and how many results there are of each value.""" 
     195        t=time.time() 
     196        src=dict(REQUEST.form.items()) 
     197        print src 
     198        # section determines what kinds of options there are: 
     199        path=REQUEST['ACTUAL_URL'].split('/') 
     200        force_language=True 
     201 
     202        if 'content' in path: 
     203            do_languages=True 
     204            do_subject_areas=True 
     205            do_target_groups=True 
     206            do_types=True 
     207            type_selection=CONTENT_TYPES 
     208            do_edited=True 
     209            do_tags=True 
     210            count_indexes=('Language','getTarget_group','portal_type','getSubject_area') 
     211        elif 'methods' in path or 'tools' in path: 
     212            do_languages=True 
     213            do_subject_areas=False 
     214            do_target_groups=False 
     215            do_types=False 
     216            do_edited=True 
     217            do_tags=True 
     218            count_indexes=('Language',) 
     219        elif 'community' in path: 
     220            do_languages=True 
     221            do_subject_areas=True 
     222            do_target_groups=False 
     223            do_types=True 
     224            type_selection=COMMUNITY_TYPES 
     225            do_edited=True 
     226            do_tags=True 
     227            count_indexes=('Language','portal_type','getSubject_area') 
     228        else: 
     229            do_languages=True 
     230            force_language=False 
     231            do_subject_areas=True 
     232            do_target_groups=True 
     233            do_types=True 
     234            type_selection=SEARCHABLE_TYPES 
     235            do_edited=True 
     236            do_tags=False 
     237            count_indexes=('Language','getTarget_group','portal_type','getSubject_area') 
     238         
     239        d={'do_languages':do_languages, 'do_subject_areas':do_subject_areas,'do_target_groups':do_target_groups,'do_types':do_types,'do_edited':do_edited, 'do_tags':do_tags, 'q':'', 'state':'', 'author':''} 
     240 
     241 
     242        # now see if the results should be counted and provide a dictionary of counted values if necessary 
     243        if results and len(results)<1000: 
     244            count_results= dict(zip(count_indexes, self.fastCount(results, count_indexes))) 
     245            count=len(results) 
     246        else: 
     247            count=0 
     248 
     249        # Languages: two lists, one for probable options and other for improbable 
     250        if do_languages: 
     251            all_languages=list(LANGUAGES)[1:] # Remove 'language neutral' from options 
     252            all_languages[0]=('','any language') 
     253            all_language_codes=[l[0] for l in all_languages] 
     254            lang_dict = getToolByName(self, 'lemill_tool').language_dict 
     255            common_language_codes=getToolByName(self,'lemill_usertool').getLanguages() 
     256            selected_language= src.get('language','') 
     257            was_empty=not selected_language 
     258            if was_empty: 
     259                if force_language: 
     260                    selected_language=common_language_codes[0] 
     261                else: 
     262                    selected_language='all' 
     263            common_languages=[] 
     264            rare_languages=[('all','All',int(selected_language=='all'),0)] 
     265            if count and was_empty and False: 
     266                langs=count_results['Language'] 
     267                for langcode in common_language_codes: 
     268                    if langcode and langcode in langs:  
     269                        common_languages.append((langcode, lang_dict[langcode], int(langcode==selected_language), langs[langcode])) 
     270                        all_language_codes.remove(langcode)             
     271                for langcode in all_language_codes: 
     272                    if langcode and langcode in langs: 
     273                        rare_languages.append((langcode, lang_dict[langcode], int(langcode==selected_language), langs[langcode])) 
     274            else: 
     275                for langcode in common_language_codes: 
     276                    common_languages.append((langcode, lang_dict[langcode], int(langcode==selected_language), 0)) 
     277                    all_language_codes.remove(langcode)             
     278                for langcode in all_language_codes: 
     279                    if langcode: 
     280                        rare_languages.append((langcode, lang_dict[langcode], int(langcode==selected_language), 0)) 
     281            d['common_languages']=common_languages 
     282            d['rare_languages']=rare_languages 
     283            d['lang_disabled']=False # portal_type==Piece can set this to true 
     284            if selected_language!='all': 
     285                d['lang_filter']='language=%s&' % selected_language 
     286            else: 
     287                d['lang_filter']='' 
     288        if do_subject_areas: 
     289            selected=src.get('subject_area','') 
     290            if selected: 
     291                all_count='?' 
     292            else: 
     293                all_count=count 
     294            subject_areas=[('','All',int(not selected), all_count)] 
     295            if count: 
     296                counts=count_results['getSubject_area'] 
     297                for sa_key,sa_full in sorted(SUBJECT_AREAS_DICT.items()): 
     298                    if sa_full in counts: 
     299                        subject_areas.append((sa_key, sa_full, int(selected==sa_key), counts[sa_full])) 
     300            else: 
     301                for sa_key,sa_full in sorted(SUBJECT_AREAS_DICT.items()): 
     302                    subject_areas.append((sa_key, sa_full, int(selected==sa_key), 0)) 
     303 
     304            d['subject_area']=subject_areas 
     305            d['subjs_disabled']=False # portal_type in ['Piece','Activity','Tool',...] will disable this 
     306        if do_target_groups: 
     307            selected=src.get('target_group','') 
     308            if selected: 
     309                all_count='?' 
     310            else: 
     311                all_count=count 
     312            target_groups=[('','All',int(not selected),all_count)] 
     313            if count: 
     314                counts=count_results['getTarget_group'] 
     315                for tg_key,tg_full in sorted(TARGET_GROUPS_DICT.items()): 
     316                    if tg_full in counts: 
     317                        target_groups.append((tg_key, tg_full, int(selected==tg_key), counts[tg_full])) 
     318            else: 
     319                for tg_key,tg_full in sorted(TARGET_GROUPS_DICT.items()): 
     320                    target_groups.append((tg_key, tg_full, int(selected==tg_key), 0)) 
     321            d['target_group']=target_groups 
     322            d['targs_disabled']=False # portal_type in ['Piece','Activity','Tool',...] will disable this 
     323        if do_types: 
     324            selected=src.get('type','') 
     325            if selected: 
     326                all_count='?' 
     327            else: 
     328                all_count=count 
     329            types=[('','All',int(not selected),all_count)] 
     330            if count: 
     331                counts=count_results['portal_type'] 
     332                for type_key in type_selection: 
     333                    if type_key in counts: 
     334                        types.append((type_key, TYPE_NAMES[type_key][1], int(selected==type_key), counts[type_key])) 
     335            else: 
     336                for type_key in type_selection: 
     337                    types.append((type_key, TYPE_NAMES[type_key][1], int(selected==type_key), 0)) 
     338            d['type']=types 
     339            if selected: 
     340                if selected in ['Piece','Activity','Tool']: 
     341                    d['targs_disabled']=True 
     342                    d['subjs_disabled']=True 
     343                if selected=='Piece': 
     344                    d['lang_disabled']=True 
     345 
     346        if do_edited: 
     347            try: 
     348                selected=int(src.get('edited',0)) 
     349            except ValueError:  
     350                selected=0 
     351            d['edited']=[('','Any time',int(not selected),0), (365,'Last year',int(selected==365),0), (30,'Last month',int(selected==30),0), (7,'Last week',int(selected==7),0), (1,'Yesterday',int(selected==1),0)] 
     352        # Previous search term 
     353        if 'q' in src: 
     354            d['q']=src['q'] 
     355        if 'state' in src: 
     356            d['state']=src['state'] 
     357        if 'author' in src: 
     358            d['author']=src['author']             
     359                 
     360        print 'creating browsing options took', time.time()-t 
     361        return d 
     362 
     363 
     364    def decideBrowsingSubType(self): 
     365        """ Browse page header needs to know what kind of browsing is going on """ 
     366        form=self.REQUEST.form         
     367        if 'state' in form: 
     368            if form['state']=='public': return 'published' 
     369            if form['state']=='draft': return 'drafts' 
     370        path=self.REQUEST['ACTUAL_URL'].split('/') 
     371        for key in ['content','methods','tools','community']: 
     372            if key in path: return key 
     373        return ''             
     374 
     375    def browsingSearch(self, REQUEST=None, **kw):         
     376        """ this search tries to use arguments from browsing form """ 
     377        print 'browsing search called' 
     378        t=time.time() 
     379        keywords={'sort_on':'getScore','sort_order':'reverse','getState':('draft', 'public')} 
     380        keywords.update(REQUEST.form.items()) 
     381        keywords.update(kw) 
     382        if 'language' in keywords: 
     383            if keywords['language']=='all': 
     384                keywords['Language']='' 
     385            else:             
     386                keywords['Language']=keywords['language'] 
     387            del keywords['language']  
     388        if 'subject_area' in keywords: 
     389            if keywords['subject_area'] in SUBJECT_AREAS_DICT: 
     390                keywords['getSubject_area']=SUBJECT_AREAS_DICT[keywords['subject_area']] 
     391            del keywords['subject_area']  
     392        if 'target_group' in keywords: 
     393            if keywords['target_group'] in TARGET_GROUPS_DICT: 
     394                keywords['getTarget_group']=TARGET_GROUPS_DICT[keywords['target_group']] 
     395            del keywords['target_group']  
     396        if 'tags' in keywords: 
     397            keywords['getTags']=keywords['tags'] 
     398            del keywords['tags'] 
     399        if 'author' in keywords: 
     400            keywords['listCreators']=keywords['author'] 
     401            del keywords['author'] 
     402        if 'state' in keywords: 
     403            keywords['getState']=keywords['state'] 
     404            del keywords['state'] 
     405        if 'type' in keywords: 
     406            keywords['portal_type']=keywords['type'] 
     407            del keywords['type']  
     408        else: # portal_type is determined by location  
     409            path=REQUEST['ACTUAL_URL'].split('/') 
     410            if 'content' in path: 
     411                keywords['portal_type']=CONTENT_TYPES 
     412            elif 'methods' in path: 
     413                keywords['portal_type']='Activity' 
     414            elif 'tools' in path: 
     415                keywords['portal_type']='Tool' 
     416            elif 'community' in path: 
     417                keywords['portal_type']=COMMUNITY_TYPES 
     418            else: 
     419                keywords['portal_type']=SEARCHABLE_TYPES 
     420        if 'q' in keywords:  
     421            keywords['SearchableText']=keywords['q'] 
     422            del keywords['q'] 
     423        if 'edited' in keywords: 
     424            keywords['getLatestEdit']={'query': self.ZopeTime()-int(keywords['edited']), 'range':'min'} 
     425        print 'keywords:', keywords 
     426        if not 'Language' in keywords: 
     427            found=False 
     428            if 'base' in keywords: 
     429                if keywords['base']=='language': 
     430                    found=True 
     431            for compensating in ['SearchableText','listCreators','getTarget_group','getTags','getSubject_area']: 
     432                if compensating in keywords: 
     433                    found=True 
     434                    break 
     435            if not found: 
     436                keywords['Language']=getToolByName(self, 'portal_languages').getLanguageCookie() or 'en' 
     437        if 'Language' in keywords: 
     438            if not keywords['Language']: 
     439                del keywords['Language'] 
     440        try: 
     441            results = self.searchResults(keywords)                 
     442        except ParseError: 
     443            results = [] 
     444        print 'browsing search:', time.time()-t 
     445        return results 
     446 
     447    #### Fast catalog handling ########################################### 
     448 
    106449    def wakeLazy(self, lazy): 
    107450        new=[] 
     
    113456        return new 
    114457 
    115  
    116     def fastMetadata(self, results, indexes): 
     458    def fastPick(self, lazy_results, top): 
     459        """ Takes Lazy results and picks one random metadata obj from top """ 
     460        tries=4 
     461        choice=randint(0,top) 
     462        while tries: # since we don't know how long the list is we need to use trial and error 
     463            # to find if the random index has corresponding item 
     464            i=0 
     465            for item in lazy_results._seq: 
     466                if choice==i: 
     467                    return lazy_results._func(item) 
     468                i+=1 
     469            choice/=2 
     470            tries-=1 
     471        return lazy_results._func(item) 
     472 
     473    def fastLink(self, user): 
     474        """ Finds an user from catalog and returns a tuple containing nicename and link  
     475        because this gets asked so often and it is relatively expensive to build, we cache them in non-permanent dict here in catalog tool 
     476        """ 
     477        if not hasattr(self, 'author_cache'): 
     478            self.author_cache={} 
     479        if not user in self.author_cache: 
     480            res=self.searchResults(Creator=user, portal_type='MemberFolder') 
     481            for l in res._seq: 
     482                authortuple= (self.getEntry('getNicename', l), self.getpath(l)) 
     483                self.author_cache[user]=authortuple 
     484                return authortuple 
     485        else: 
     486            return self.author_cache[user] 
     487        return None         
     488 
     489    def getEntry(self, index, key, empty=[]): 
     490        val=self._catalog.getIndex(index).getEntryForObject(key, empty) 
     491        if callable(val): 
     492            val=val() 
     493        return val         
     494             
     495    def fastLinks(self, results, limit): 
     496        """ Takes Lazy results and returns a list of tuples (title, url, portal_type) """ 
     497        def safeData(index, key): 
     498            v=index.getEntryForObject(key, []) 
     499            if callable(v): 
     500                return v() 
     501            return v 
     502 
     503        def wakeUp(lazy, c): 
     504            new=[] 
     505            for l in lazy._seq: 
     506                if isinstance(l, Lazy): 
     507                    c,newer=wakeUp(l,c) 
     508                    new.extend(newer) 
     509                else: 
     510                    new.append((safeData(title_index, l), self.getpath(l), safeData(type_index, l))) 
     511                    c+=1 
     512                if c==limit: 
     513                    break 
     514            return c,new 
     515        title_index=self._catalog.getIndex('getNicename') 
     516        type_index=self._catalog.getIndex('portal_type') 
     517        c,new=wakeUp(results,0)         
     518        return new 
     519 
     520    def fastMetadata(self, results, indexes, cut=0): 
    117521        """ Takes Lazy results and returns a list of tuple for values from indexes. 
    118522        Indexes is a string or a tuple of strings. 
    119523        This is an order of magnitude faster than getting CatalogBrains for each object""" 
    120         def wakeUp(lazy): 
     524        c=0 
     525        def safeData(index, key): 
     526            v=index.getEntryForObject(key, []) 
     527            if callable(v): 
     528                return v() 
     529            return v 
     530 
     531        def wakeUp(lazy,c): 
    121532            new=[] 
    122             for l in lazy._seq: 
     533            if isinstance(lazy, list): 
     534                seq=lazy 
     535            else: 
     536                seq=lazy._seq 
     537            for l in seq: 
    123538                if isinstance(l, Lazy): 
    124                     new.extend(wakeUp(l)) 
     539                    new.extend(wakeUp(l,c)) 
    125540                else: 
    126541                    values=[]     
    127542                    for index in index_sources: 
    128                         if index:             
    129                             values.append(index.getEntryForObject(l, [])) 
     543                        if index: 
     544                            values.append(safeData(index, l)) 
    130545                        else: 
    131546                            values.append(l)  
    132547                    new.append(tuple(values)) 
     548                    c+=1 
     549                    if c==cut: 
     550                        break 
    133551            return new 
    134         def wakeUpFaster(lazy): 
     552        def wakeUpFaster(lazy, c): 
    135553            new=[] 
    136             for l in lazy._seq: 
     554            if isinstance(lazy, list): 
     555                seq=lazy 
     556            else: 
     557                seq=lazy._seq 
     558            for l in seq: 
    137559                if isinstance(l, Lazy): 
    138                     new.extend(wakeUpFaster(l)) 
     560                    new.extend(wakeUpFaster(l,c)) 
    139561                else: 
    140562                    new.append(index.getEntryForObject(l, [])) 
     563                c+=1 
     564                if c==cut: 
     565                    break 
    141566            return new 
    142         if isinstance(indexes, tuple): 
     567        if isinstance(indexes, tuple) or isinstance(indexes, list): 
    143568            index_sources=[ind!='rid' and self._catalog.getIndex(ind) for ind in indexes] 
    144             new=wakeUp(results) 
     569            new=wakeUp(results,c) 
    145570        else: 
    146571            index=self._catalog.getIndex(indexes) 
    147             new=wakeUpFaster(results) 
     572            new=wakeUpFaster(results,c) 
    148573        return new 
    149574         
     
    152577        Index is a string or tuple of strings.  
    153578        This is an order of magnitude faster than getting CatalogBrains for each object""" 
     579 
     580        def safeData(index, key): 
     581            v=index.getEntryForObject(key, []) 
     582            if callable(v): 
     583                return v() 
     584            return v 
     585         
    154586        def wakeUpAndCount(lazy): 
    155587            for l in lazy._seq: 
     
    159591                    values=[]     
    160592                    for dic, index in indexes: 
    161                         val=index.getEntryForObject(l, []) 
     593                        val=safeData(index, l) 
    162594                        if val: 
    163595                            if isinstance(val, list): 
     
    172604                    wakeUpFasterAndCount(l) 
    173605                else: 
    174                     val=index.getEntryForObject(l, []) 
     606                    val=safeData(index, l) 
    175607                    if isinstance(val, list): 
    176608                        for v in val:                         
     
    181613        index=None 
    182614        if isinstance(indexes, tuple): 
     615            if not results: 
     616                return [{} for ind in indexes] 
    183617            indexes=[({}, self._catalog.getIndex(ind)) for ind in indexes] 
    184618            new=wakeUpAndCount(results) 
    185619            return tuple([dic for dic,index in indexes]) 
    186620        else: 
     621            if not results: 
     622                return {} 
    187623            index=self._catalog.getIndex(indexes) 
    188624            dic={} 
     
    193629        record = self._catalog.data[rid] 
    194630        schema = self._catalog.schema 
    195         result = {} 
    196         for md in md_fields: 
    197             result[md]= record[schema[md]] 
    198         return result 
     631        if isinstance(md_fields, (tuple, list)): 
     632            result = {} 
     633            for md in md_fields: 
     634                result[md]= record[schema[md]] 
     635            return result 
     636        else: 
     637            return record[schema[md_fields]] 
     638 
     639 
     640    ##############################      Clouds      ########################   
     641 
     642    def buildCloudData(self, results, request=None): 
     643        """ Build tag cloud result tuples (name, tagsize, obj_url, tag_value, nicename) for given form from result set """  
     644        def adjustTag(val, steps=8): 
     645            # helper method to adjust hit count of this tag to relative size (1,...,8)  
     646            try: 
     647                val=int((8*log(val-mincount,2))/log(maxcount-mincount,2)) 
     648            except (OverflowError, ZeroDivisionError): 
     649                val=0 
     650            if not val: 
     651                val=1 
     652            return val 
     653        lemill_tool = getToolByName(self, 'lemill_tool') 
     654        if not results: 
     655            return []         
     656        src=dict(request.form.items()) 
     657        if 'base' not in src: 
     658            return []  
     659        portal_url=getToolByName(self, 'portal_url')() 
     660        path=request['ACTUAL_URL'].split('/') 
     661        if 'content' in path:  
     662            link_base='/'.join((portal_url,'content','browse')) 
     663        elif 'methods' in path: 
     664            link_base='/'.join((portal_url,'methods','browse')) 
     665        elif 'tools' in path: 
     666            link_base='/'.join((portal_url,'tools','browse')) 
     667        elif 'community' in path: 
     668            link_base='/'.join((portal_url,'community','browse')) 
     669        else: 
     670            link_base='/'.join((portal_url,'browse'))         
     671        lang_part='' 
     672        base=src['base'] 
     673        language=src.get('language','') 
     674        if language: 
     675            lang_part='language=%s&' % language 
     676        title_cloud=False 
     677        if base=='language': 
     678            link_root='%s?language=' % link_base         
     679            cloud_index='Language' 
     680        elif base=='tags': 
     681            link_root='%s?%stags=' % (link_base, lang_part)        
     682            cloud_index='getTags' 
     683        elif base=='subject_area': 
     684            link_root='%s?%ssubject_area=' % (link_base, lang_part)        
     685            cloud_index='getSubject_area' 
     686        elif base=='target_group': 
     687            link_root='%s?%starget_group=' % (link_base, lang_part)        
     688            cloud_index='getTarget_group' 
     689        elif base=='title': 
     690            resultlist=self.fastMetadata(results, ('sortable_title','getScore','getNicename', 'path'), cut=100) 
     691            maxcount=resultlist[0][1] 
     692            mincount=resultlist[-1][1]              
     693            resultlist.sort() 
     694            resultlist=[(x[2], adjustTag(x[1], steps=6), x[3]) for x in resultlist if x[2]]  
     695            return resultlist 
     696             
     697        hits=self.fastCount(results, cloud_index) 
     698        resultlist=zip(hits.values(),hits.keys()) 
     699        resultlist.sort(reverse=True) 
     700        maxcount=resultlist[0][0] # first! 
     701        resultlist = resultlist[:100] 
     702        mincount=resultlist[-1][0] # last! 
     703        # At this point resultlist= [(number_of_hits, tag_text),...] 
     704        # It should end up as: [(displayed_text, number_of_hits, link_url)...] 
     705        if cloud_index=='Language' or cloud_index=='getLanguage_skills': 
     706            resultlist=[(lemill_tool.getPrettyLanguage(x[1]), adjustTag(x[0]), ''.join((link_root, x[1]))) for x in resultlist]             
     707        elif cloud_index=='getSubject_area': 
     708            resultlist=[(x[1], adjustTag(x[0]), ''.join((link_root, SUBJECT_AREAS_INVERSE_DICT.get(x[1], x[1])))) for x in resultlist]             
     709        elif cloud_index=='getTarget_group': 
     710            resultlist=[(x[1], adjustTag(x[0]), ''.join((link_root, TARGET_GROUPS_INVERSE_DICT.get(x[1], x[1])))) for x in resultlist]             
     711        else: 
     712            resultlist=[(x[1], adjustTag(x[0]), ''.join((link_root, x[1]))) for x in resultlist]             
     713        resultlist.sort() 
     714        return resultlist 
     715 
     716    ########### Front page top lists ############ 
     717     
     718    def getTopFive(self, results=None, key_index=None, link_body='', clean=False): 
     719        """ Returns top five results for key_index (getTags, getSubject_area...) for certain language """ 
     720        if clean or not hasattr(self, 'top5results'): 
     721            self.top5results={'content':{}, 'methods':{}, 'tools':{}, 'community':{}} 
     722        data=self.top5results 
     723        path=self.REQUEST['ACTUAL_URL'].split('/') 
     724        for section in ['content','methods','tools','community',None]: 
     725            if section in path: 
     726                break 
     727        if not section: 
     728            return [] 
     729        ilanguage=getToolByName(self, 'portal_languages').getLanguageCookie() or 'en' 
     730        if key_index in data[section]: 
     731            top5lists=data[section][key_index] 
     732        else: 
     733            top5lists={} 
     734            data[section][key_index]=top5lists 
     735        if ilanguage in top5lists: 
     736            return top5lists[ilanguage] 
     737        else: 
     738            tops=self.fastCount(results, key_index) 
     739            resultlist=zip(tops.values(),tops.keys()) 
     740            resultlist.sort(reverse=True) 
     741            resultlist=resultlist[:5] 
     742            if key_index=='getSubject_area': 
     743                resultlist=[(x[1], ''.join((link_body, SUBJECT_AREAS_INVERSE_DICT.get(x[1], x[1])))) for x in resultlist] 
     744            elif key_index=='getTarget_group': 
     745                resultlist=[(x[1], ''.join((link_body, TARGET_GROUPS_INVERSE_DICT.get(x[1], x[1])))) for x in resultlist] 
     746            else: 
     747                resultlist=[(x[1], ''.join((link_body, x[1]))) for x in resultlist] 
     748            top5lists[ilanguage]=resultlist 
     749            print top5lists 
     750            return resultlist 
     751 
     752    ############################# batch ########################## 
     753 
     754    def batch(self, results=None, request=None): 
     755        """ Use Plone's batch """ 
     756        if request and 'b_start' in request.form: 
     757            try: 
     758                b_start=int(request.form['b_start']) 
     759            except ValueError: 
     760                b_start=0 
     761        else: 
     762            b_start=0   
     763        b= Batch(results, 30, b_start, orphan=1)     
     764        return b   
     765 
     766    def batchBaseUrl(self): 
     767        """ Keep all other parametres as they are, but add or change 'b_start' """ 
     768        form=self.REQUEST.form 
     769        if 'b_start' in form: 
     770            del form['b_start']  
     771        last_url='?'.join((self.REQUEST.ACTUAL_URL, urlencode(form))) 
     772        new= last_url+'&b_start=%s' 
     773        return new 
     774         
     775 
     776# 
     777#    def getTagCloud(self, search_results, index_type): 
     778#        """ Build a cloud based on how many occurences of this item are in results """ 
     779#        if not search_results: 
     780#            return [] 
     781#        lemill_tool = getToolByName(self, 'lemill_tool') 
     782#        pc = getToolByName(self, 'portal_catalog') 
     783#        from math import log 
     784#        maxcount=0 
     785# 
     786#        hits={} 
     787#        hits=pc.fastCount(search_results, index_type) 
     788#        resultlist=zip(hits.values(),hits.keys()) 
     789#        if not resultlist: 
     790#            return [] 
     791#        resultlist.sort() 
     792#        resultlist.reverse() 
     793#        maxcount=resultlist[0][0] # first! 
     794#        # if the first cut score for tag is x, we want to cut off all of the tags with score x.  
     795#        if len(resultlist)>100: 
     796#            #cutpoint = [x[0] for x in resultlist].index(resultlist[100]) can't figure this now, fix later 
     797#            cutpoint = 100 
     798#            resultlist = resultlist[:cutpoint] 
     799#        mincount=resultlist[-1][0] 
     800#        resultlist=[(x[1], x[0], '',x[1],x[1]) for x in resultlist] 
     801# 
     802#        # adjust to 1-8. We don't have to worry about score 0, they're already removed. 
     803#        if maxcount>1: 
     804#            resultlist=map(adjust, resultlist) 
     805#        # prettify language names 
     806#        if index_type=='Language' or index_type=='getLanguage_skills': 
     807#            resultlist=[(x[0],x[1],x[2],x[3],lemill_tool.getPrettyLanguage(x[4])) for x in resultlist]             
     808#        if index_type=='getTarget_group': 
     809#            def compfunc(t2,t1): 
     810#                if t2[0] in TARGET_GROUP and t1[0] in TARGET_GROUP: 
     811#                    return  TARGET_GROUP.index(t2[0]) - TARGET_GROUP.index(t1[0]) 
     812#                else: 
     813#                    return -1 
     814#            resultlist.sort(cmp=compfunc) 
     815#        else:     
     816#            resultlist.sort() 
     817#        return resultlist 
     818#         
     819# 
     820#    def getTitleCloud(self, search_results, browse_type): 
     821#        """ Build a cloud based on popularity score for that resource """ 
     822#        pc=getToolByName(self,'portal_catalog') 
     823#        # uniquetuplelist contains result metadata reordered: (sort_title, count, url, indexvalue, title) 
     824#        if not search_results: 
     825#            return [] 
     826# 
     827#        def isDefaultTitle(x): 
     828#            """ some heuristic to recognize default titles """ 
     829#            return re.match(r'.*\.(...)$', x) or re.match(r'.*\.(....)$', x)  
     830#                     
     831#        popularity = pc.fastMetadata(search_results, ('getScore','rid','getNicename','sortable_title')) 
     832#        popularity.sort(reverse=True) 
     833#        popularity=popularity[:100] 
     834#        titlecloud=[(sortable_title, getScore, self.REQUEST.physicalPathToURL(pc.getpath(rid)), sortable_title, getNicename or sortable_title) for (getScore, rid, getNicename, sortable_title) in popularity if sortable_title] 
     835#         
     836#        if not titlecloud: 
     837#            return [] 
     838#        titlecloud.sort() 
     839#        maxscore=max([x[1] for x in titlecloud]) 
     840#        if maxscore>1: 
     841#            titlecloud=map(adjust, titlecloud) 
     842#        return titlecloud 
     843 
     844 
     845 
    199846 
    200847 
  • trunk/LeMillTool.py

    r3045 r3052  
    2424from Globals import InitializeClass 
    2525from AccessControl import ClassSecurityInfo 
    26 from config import TYPE_NAMES, SEARCHABLE_TYPES, CONTENT_TYPES, COMMUNITY_TYPES, TOOLS_TYPES, ACTIVITY_TYPES, MATERIAL_TYPES, STATISTICS_TYPES, GOOD_STORIES_ONLY, MIMETYPE_WHITELIST, SECTIONS, RECAPTCHA_PUBLIC_KEY, RECAPTCHA_PRIVATE_KEY, to_unicode 
     26from config import TYPE_NAMES, SEARCHABLE_TYPES, CONTENT_TYPES, COMMUNITY_TYPES, TOOLS_TYPES, ACTIVITY_TYPES, MATERIAL_TYPES, STATISTICS_TYPES, GOOD_STORIES_ONLY, MIMETYPE_WHITELIST, SECTIONS, RECAPTCHA_PUBLIC_KEY, RECAPTCHA_PRIVATE_KEY, to_unicode, LANGUAGES 
    2727from permissions import MANAGE_PORTAL, ModerateContent, ADD_CONTENT_PERMISSION 
    2828from Resource import Resource 
     
    865865    def getPrettyLanguage(self, lang_code): 
    866866        if len(str(lang_code))<3: 
    867             ts=getToolByName(self,'translation_service') 
    868             languages = ts.availableLanguages() 
    869             if dict(languages).has_key(lang_code): 
    870                 return dict(languages)[lang_code] 
     867            if lang_code in self.language_dict: 
     868                return self.language_dict[lang_code] 
    871869            else: 
    872870                return lang_code 
     
    882880        piece.at_post_edit_script() 
    883881 
     882 
    884883    def buildLanguageLinks(self): 
     884        """ build links from primary languages """ 
     885        return [(lang, ''.join(('setLang?lang=',lang))) for lang in self.primary_languages] 
     886 
     887    def buildLanguageLinksOld(self): 
    885888        """ returns a list of (lang, url) tuples for language links to this resource """  
    886889        stri = self.REQUEST.get('QUERY_STRING') 
     
    892895        return [(lang, ''.join((linkbase, lang, param))) for lang in self.primary_languages] 
    893896 
    894     def getStoryCandidate(self, only_with_story=True): 
    895         """ Random pick for one content, method and tool or story if only_with_story """ 
     897    def getFeaturedItems(self): 
     898        """ Fetch items for front page. Try to use languages that user would like to see. """ 
     899        t=time.time() 
    896900        pc=getToolByName(self, 'portal_catalog')         
    897         ltool = getToolByName(self, 'portal_languages') 
    898901        lutool=getToolByName(self, 'lemill_usertool') 
    899         favlang = ltool.getLanguageCookie() 
    900         stories=[] 
    901         if favlang: 
    902             favlang=[favlang] 
    903         else: 
    904             mf=lutool.getMemberFolder() 
    905             if mf: 
    906                 favlang=list(mf.getLanguage_skills()) 
    907             else: 
    908                 favlang=[]             
    909         if GOOD_STORIES_ONLY and only_with_story: 
    910             if favlang: 
    911                 stories=pc({'getGoodStory':True, 'Language':favlang, 'portal_type':'Collection', 'getState':'public'})             
    912             if not stories: 
    913                 stories=pc({'getGoodStory':True, 'portal_type':'Collection', 'getState':'public'}) 
    914             if not stories: 
    915                 return self.getStoryCandidate(only_with_story=False) 
    916             story=choice(stories) 
    917             story=story.getObject() 
    918             content=story.getRelatedContentMetadata(getHasCoverImage=True) 
    919             method=story.getRelatedMethodsMetadata(getHasCoverImage=True) 
    920             tool=story.getRelatedToolsMetadata(getHasCoverImage=True) 
    921             if content: 
    922                 content=choice(content) 
    923             if method: 
    924                 method=choice(method) 
    925             if tool: 
    926                 # getObject verified 
    927                 tool=choice(tool) 
    928         else:         
    929             full_results=pc({'getState':'public','getHasCoverImage':True}) 
    930             content=[x for x in full_results if x.meta_type in MATERIAL_TYPES] 
    931             method=[x for x in full_results if x.meta_type=='Activity'] 
    932             tool=[x for x in full_results if x.meta_type=='Tool'] 
    933             if content: 
    934                 # getObject verified 
    935                 content=choice(content) 
    936             if method: 
    937                 # getObject verified 
    938                 method=choice(method) 
    939             if tool: 
    940                 # getObject verified 
    941                 tool=choice(tool) 
    942             if content and method and tool: 
    943                 stories=pc({'portal_type':'Collection'}) 
    944                 if stories: 
    945                     story=choice(stories) 
    946                     # getObject verified 
    947                     story=story.getObject() 
    948                 else: 
    949                     story=None 
    950             else: 
    951                 story=None 
    952         candidate = {'chcontent':content, 'method':method, 'tool':tool, 'story':story} 
    953         return candidate 
    954          
     902        languages= lutool.getLanguages() 
     903        content={'absolute_url':'content', 'title':'Content','cover_url':'images/default_multimedia_page.png'} 
     904        method={'absolute_url':'methods', 'title':'Methods','cover_url':'images/default_method.png'} 
     905        tool={'absolute_url':'tools', 'title':'Tools','cover_url':'images/default_tool.png'} 
     906        community={'absolute_url':'community', 'title':'Community','cover_url':'images/default_member.png'} 
     907        for lang in languages: 
     908            res=pc({'getHasCoverImage':True, 'Language':lang, 'portal_type':MATERIAL_TYPES, 'getState':'public', 'sort_on':'getScore','sort_order':'descending'}) 
     909            if res:                 
     910                md=pc.fastPick(res, 30) 
     911                content={'absolute_url':'%s/view' % md.getURL(), 'title':md.Title, 'cover_url': '%s/coverImage' % md.getURL()} 
     912                break 
     913        for lang in languages: 
     914            res=pc({'getHasCoverImage':True, 'Language':lang, 'portal_type':'Activity', 'getState':'public', 'sort_on':'getScore','sort_order':'descending'}) 
     915            if res: 
     916                md=pc.fastPick(res, 30) 
     917                method={'absolute_url':md.getURL(), 'title':md.Title, 'cover_url': '%s/coverImage' % md.getURL()} 
     918                break 
     919        for lang in languages: 
     920            res=pc({'getHasCoverImage':True, 'Language':lang, 'portal_type':'Tool', 'getState':'public', 'sort_on':'getScore','sort_order':'descending'}) 
     921            if res: 
     922                md=pc.fastPick(res, 30) 
     923                tool={'absolute_url':md.getURL(), 'title':md.Title, 'cover_url': '%s/coverImage' % md.getURL()} 
     924                break 
     925        for lang in languages: 
     926            res=pc({'getHasCoverImage':True, 'getLanguageSkills':lang, 'portal_type':'MemberFolder', 'getState':'public','sort_on':'getScore','sort_order':'descending'}) 
     927            if res: 
     928                md=pc.fastPick(res, 30) 
     929                community={'absolute_url':md.getURL(), 'title':md.Title, 'cover_url': '%s/coverImage' % md.getURL()} 
     930                break 
     931        print 'building featured items took:', time.time()-t 
     932        return {'content':content,'method':method,'tool':tool,'community':community}              
     933 
     934    def getLeMillStats(self): 
     935        """ Returns stats to display in lemill front page """ 
     936        pc=getToolByName(self, 'portal_catalog')         
     937        week_ago={'query': self.ZopeTime()-7, 'range':'min'} 
     938        d={'teachers':0, 'countries':0,'learning_resources':0,'languages':0,'weekly_members':0,'weekly_new':0,'weekly_edited':0} 
     939        d['teachers']=len(pc({'portal_type':'MemberFolder', 'getState':'public'})) 
     940        d['countries']=len(pc.uniqueValuesFor('getLocation_country'))-2 # 'No country specified' and another empty field marker shouldn't count 
     941        d['learning_resources']=len(pc({'portal_type':MATERIAL_TYPES + ACTIVITY_TYPES + TOOLS_TYPES, 'getState':'public'})) 
     942        d['languages']=len(pc.uniqueValuesFor('Language'))-2 # same as with countries 
     943        d['weekly_members']=len(pc({'portal_type':'MemberFolder', 'getState':'public', 'created':week_ago})) 
     944        d['weekly_new']=len(pc({'portal_type':MATERIAL_TYPES + ACTIVITY_TYPES + TOOLS_TYPES, 'getState':'public', 'created':week_ago})) 
     945        d['weekly_edited']=len(pc({'portal_type':MATERIAL_TYPES + ACTIVITY_TYPES + TOOLS_TYPES, 'getState':'public', 'modified':week_ago})) 
     946        return d 
    955947         
    956948    def getTimeDifference(self,modtime, seconds=False): 
     
    11231115 
    11241116 
    1125     def advancedSearch(self, REQUEST): 
    1126         """ ordering only by score """ 
    1127         if '-C' in REQUEST.form.keys(): 
    1128             return [] 
    1129         empty=True 
    1130         for key, value in REQUEST.form.items(): 
    1131             if value and key!='submit': 
    1132                 empty=False         
    1133         if empty: 
    1134             return [] 
    1135         pc = getToolByName(self, 'portal_catalog') 
    1136         try: 
    1137             if 'getState' not in REQUEST.form.keys(): 
    1138                 results = pc(REQUEST, getState=('draft', 'public'), sort_on='getScore', sort_order='reverse') 
    1139             else: 
    1140                 results = pc(REQUEST, sort_on='getScore', sort_order='reverse') 
    1141         except ParseError: 
    1142             results = [] 
    1143         return results 
    11441117         
    11451118    def OrderingSearch(self, REQUEST=None, **kw): 
     
    14661439        #data['mtool'] = mtool = getToolByName(portal, 'portal_membership') 
    14671440        data['lutool'] = lutool = getToolByName(portal, 'lemill_usertool') 
     1441        data['lemill_tool'] = self 
    14681442        # BBB: gtool is deprecated because it is only used in sepcialized 
    14691443        # contexts 
     
    16291603        return pc(portal_type=portal_type, getState="public") 
    16301604 
     1605    def getTime(self): 
     1606        """ Allow timing for ext. python scripts """  
     1607        return time.time() 
     1608 
     1609    def dumpMe(self, item): 
     1610        """ Allow printing to terminal from python script """ 
     1611        print item 
    16311612 
    16321613InitializeClass(LeMillTool) 
  • trunk/LeMillUserTool.py

    r2986 r3052  
    3535from Products.PluggableAuthService.interfaces.authservice \ 
    3636        import IPluggableAuthService 
    37 import re 
     37import re, time 
    3838 
    3939_marker = object() 
     
    111111        will build html link '<a href="h**p://lemillserver/community/people/username">Users NiceName</a>' 
    112112        """  
     113        t=time.time() 
    113114        md= self.getMemberFolderMetadata(memberid) 
    114115        if not md: 
     
    121122            return "".join(('<a target="_blank" href="',md.getURL(), '"',i18name,'>',str(md.getNicename),'</a>')) 
    122123        else: 
     124            print 'linkTo:', time.time()-t 
    123125            return "".join(('<a href="',md.getURL(), '"',i18name,'>',str(md.getNicename),'</a>')) 
    124126         
  • trunk/LearningResource.py

    r3045 r3052  
    2727from Resource import Resource 
    2828from Discussable import Discussable 
     29from config import LANGUAGES 
    2930 
    3031# This is used by pdf cleaning method prepareForPDF  
     
    210211        for field in base_obj.schema.values(): 
    211212            # list all fields here that shouldn't be copyied to new object 
    212             if not getattr(field, 'copied_in_translation', False) or field.getName()=='id': 
     213            if not getattr(field, 'copied_in_translation', False) or field.getName() in ['id', 'groupEditing']: 
    213214                continue 
    214215            old_accessor = field.getEditAccessor(base_obj) 
     
    242243        """ List of languages minus list of existing translations """ 
    243244        transcodes = set([x.Language() for x in self.getTranslationsOfOriginal(include_original=True)]) 
    244         return [x for x in self.availableLanguages()[1:] if x[0] not in transcodes] 
     245        return [x for x in LANGUAGES[1:] if x[0] not in transcodes] 
    245246 
    246247 
  • trunk/MemberFolder.py

    r3032 r3052  
    432432     
    433433    def getLanguagelist(self): 
    434         languagelist=self.availableLanguages() 
    435         return DisplayList(languagelist[1:]) # Cut out the first, 'no language specified'-option 
     434        return DisplayList(LANGUAGES[1:]) # Cut out the first, 'no language specified'-option 
    436435 
    437436 
  • trunk/PILOTMaterial.py

    r3045 r3052  
    2929 
    3030pilotmaterial_schema = Schema(( 
     31 
     32 
    3133    StringField('shortDescription', 
    3234        index=None, 
  • trunk/Resource.py

    r3045 r3052  
    2222from Products.CMFCore.utils import getToolByName 
    2323from AccessControl import ClassSecurityInfo, Unauthorized 
    24 from config import MATERIAL_TYPES, TARGET_GROUP_TO_LRE_MAPPING, SUBJECT_AREA_TO_LRE_MAPPING, PORTAL_TYPE_TO_LRE_MAPPING, to_unicode 
     24from config import MATERIAL_TYPES, TARGET_GROUP_TO_LRE_MAPPING, SUBJECT_AREA_TO_LRE_MAPPING, PORTAL_TYPE_TO_LRE_MAPPING, to_unicode, LANGUAGES 
    2525from persistent.list import PersistentList 
    2626from messagefactory_ import i18nme as _ 
     
    261261 
    262262    def getLanguagelist(self): 
    263         languagelist=self.availableLanguages() 
    264         return DisplayList(languagelist)  
     263        return DisplayList(LANGUAGES)  
    265264 
    266265    security.declarePublic('defaultLanguage') 
  • trunk/Schemata.py

    r3002 r3052  
    2121from Products.Archetypes.public import * 
    2222from FieldsWidgets import * 
    23 from config import LICENSES, ALL_LICENSES, SUBJECT_AREAS 
     23from config import LICENSES, ALL_LICENSES, SUBJECT_AREAS, TARGET_GROUPS 
    2424 
    2525 
     
    311311        enforceVocabulary = False, 
    312312        multiValued = True, 
    313         copied_in_translation=True, 
     313        copied_in_translation=False, 
    314314        copied_in_branching=False, 
    315315        widget=GroupWidget( 
     
    328328target_group_schema = Schema(( 
    329329    LinesField('target_group', 
    330         vocabulary = DisplayList(( 
    331             ("pre-school education", "pre-school education"), 
    332             ("1st grade", "1st grade"), 
    333             ("2nd grade", "2nd grade"), 
    334             ("3rd grade", "3rd grade"), 
    335             ("4th grade", "4th grade"), 
    336             ("5th grade", "5th grade"), 
    337             ("6th grade", "6th grade"), 
    338             ("7th grade", "7th grade"), 
    339             ("8th grade", "8th grade"), 
    340             ("9th grade", "9th grade"), 
    341             ("10th grade", "10th grade"), 
    342             ("11th grade", "11th grade"), 
    343             ("12th grade", "12th grade"), 
    344             ("higher education", "higher education"), 
    345             ("adult education","adult education"), 
    346             ("teachers", "teachers"), 
    347             ("special education", "special education"), 
    348             )), 
     330        vocabulary = DisplayList(zip(TARGET_GROUPS,TARGET_GROUPS)), 
    349331        index = "KeywordIndex:schema", 
    350332        multivalued=True, 
     
    364346subject_area_schema = Schema(( 
    365347    LinesField('subject_area', 
    366         vocabulary = DisplayList([(x,x) for x in SUBJECT_AREAS]), 
     348        vocabulary = DisplayList(zip(SUBJECT_AREAS,SUBJECT_AREAS)), 
    367349        index = "KeywordIndex:schema", 
    368350        multivalued=True, 
  • trunk/config.py

    r3045 r3052  
    169169        "Educational administration", 
    170170        "Cross-curricular education"] 
     171SUBJECT_AREAS_DICT= dict([(sa.split()[0].lower(),sa) for sa in SUBJECT_AREAS]) 
     172SUBJECT_AREAS_INVERSE_DICT= dict([(sa, sa.split()[0].lower()) for sa in SUBJECT_AREAS]) 
     173 
     174TARGET_GROUPS= ["pre-school education",  
     175            "1st grade",  
     176            "2nd grade",  
     177            "3rd grade",  
     178            "4th grade",  
     179            "5th grade",  
     180            "6th grade",  
     181            "7th grade",  
     182            "8th grade",  
     183            "9th grade",  
     184            "10th grade",  
     185            "11th grade",  
     186            "12th grade",  
     187            "higher education", 
     188            "adult education", 
     189            "teachers",  
     190            "special education"] 
     191 
     192TARGET_GROUPS_DICT= dict([(tg.split()[0].lower(),tg) for tg in TARGET_GROUPS]) 
     193TARGET_GROUPS_INVERSE_DICT = dict([(tg, tg.split()[0].lower()) for tg in TARGET_GROUPS]) 
     194 
    171195 
    172196 
     
    267291    } 
    268292 
    269 # Topic configurations for SECTION_TOPICS 
    270 # The idea for topics is that there are few special topics like language, tags, skills, target_group etc. that exist solely to provide tag clouds arranged by values for that field.  
    271 # 
    272 # 
    273  
    274  
    275 #put these to dictionary so it won't mess the namespace 
    276  
    277  
    278 DEFAULT_TOPIC_VIEW= "lemill_browse_results" 
    279  
    280 # {folder : [(allowed_types, (topic1_conf,topic2_conf)), (allowed_types, (topic1_conf... 
    281  
    282 SECTION_TOPICS = { 
    283     'Content':  
    284     # *********************** 
    285     [(CONTENT_TYPES, (  
    286     {'id':'tags', 'title':'Tags', 'getmethod':'getTags', 'view':'lemill_browse_content'}, 
    287     {'id':'published', 'title':'Published', 'view':'lemill_published_content', 'sortby':'getLatestEdit', 'reversed':True, 'criterions':[('ATCurrentAuthorCriterion','Creator',''),('ATSelectionCriterion','getState','public')]},)), 
    288     # +++++++++++++++++++++++ 
    289     (MATERIAL_TYPES, (  
    290     {'id':'browse_resources', 'title':'Resources', 'view':'lemill_content_titlecloud'}, 
    291     {'id':'drafts', 'title':'Draft', 'view':'lemill_published_view', 'sortby':'getLatestEdit', 'reversed':True,'criterions':[('ATCurrentAuthorCriterion','Creator',''),('ATSelectionCriterion','getState',['draft','private'])]},)), 
    292     # +++++++++++++++++++++++ 
    293     (MATERIAL_TYPES+('LeMillPrintResource',), (  
    294     {'id':'language', 'title':'Language', 'getmethod':'Language', 'view':'lemill_browse_content'}, 
    295     {'id':'subject_area', 'title':'Subject area', 'getmethod':'getSubject_area', 'view':'lemill_browse_content'}, 
    296     {'id':'target_group', 'title':'Target group', 'getmethod':'getTarget_group', 'view':'lemill_browse_content'},)), 
    297     # +++++++++++++++++++++++ 
    298     (('LeMillReference',), (  
    299     {'id':'browse_references', 'title':'References', 'view':'lemill_content_titlecloud'},)), 
    300     # +++++++++++++++++++++++ 
    301     (('LeMillPrintResource',), ( 
    302     {'id':'browse_printresources', 'title':'Print resources', 'view':'lemill_content_titlecloud'},)), 
    303     # +++++++++++++++++++++++ 
    304     (('Piece',), (  
    305     {'id':'browse_pieces', 'title':'Pieces', 'view':'lemill_content_titlecloud'},)), 
    306     # +++++++++++++++++++++++ 
    307      (MATERIAL_TYPES+ACTIVITY_TYPES+TOOLS_TYPES+COMMUNITY_TYPES+('LeMillPrintResource',), ( 
    308     {'id':'recent', 'title':"What's going on", 'getmethod':'getLatestEdit', 'sortby':'getLatestEdit', 'reversed':True, 'view':'lemill_recent_view'},)) 
    309     # +++++++++++++++++++++++ 
    310     ], 
    311  
    312     'Methods':  
    313     # *********************** 
    314     [(('Activity',),(  
    315     {'id':'language', 'title':'Language', 'getmethod':'Language','view':'lemill_browse_methods'}, 
    316     {'id':'tags', 'title':'Tags', 'getmethod':'getTags','view':'lemill_browse_methods'}, 
    317     {'id':'published', 'title':'Published', 'view':'lemill_published_view', 'sortby':'getLatestEdit', 'reversed':True,'criterions':[('ATCurrentAuthorCriterion','Creator',''),('ATSelectionCriterion','getState','public')]}, 
    318     {'id':'browse_methods', 'title':'Methods', 'view':'lemill_titlecloud'})) 
    319     ], 
    320  
    321     'Tools':  
    322     # *********************** 
    323     [(('Tool',),(  
    324     {'id':'language', 'title':'Language', 'getmethod':'Language','view':'lemill_browse_tools'}, 
    325     {'id':'tags', 'title':'Tags', 'getmethod':'getTags','view':'lemill_browse_tools'}, 
    326     {'id':'published', 'title':'Published', 'view':'lemill_published_view', 'sortby':'getLatestEdit', 'reversed':True, 'criterions':[('ATCurrentAuthorCriterion','Creator',''),('ATSelectionCriterion','getState','public')]}, 
    327     {'id':'browse_tools', 'title':'Tools', 'view':'lemill_titlecloud'})) 
    328     ], 
    329  
    330     'Community': 
    331     # *********************** 
    332     [(CONTENT_TYPES + ACTIVITY_TYPES + TOOLS_TYPES+('GroupBlog',),( 
    333     {'id':'portfolio', 'title':'Portfolio', 'getmethod':'getTags', 'sortby':'getLatestEdit', 'reversed':True, 'view':'lemill_portfolio_view'},)), 
    334     # +++++++++++++++++++++++ 
    335     (('MemberFolder',),( 
    336     {'id':'browse_people', 'title':'Members', 'getmethod':'sortable_title', 'view':'lemill_titlecloud'}, 
    337     {'id':'language', 'title':'Language', 'getmethod':'getLanguage_skills', 'view':'lemill_browse_members'}, 
    338     {'id':'country', 'title':'Location', 'getmethod':'getLocation_country', 'view':'lemill_browse_members'}, 
    339     {'id':'skills', 'title':'Skills', 'getmethod':'getSkills', 'view':'lemill_browse_members'}, 
    340     {'id':'interests', 'title':'Interests',  'getmethod':'getInterests', 'view':'lemill_browse_members'}, 
    341     {'id':'subject_area', 'title':'Subject area', 'getmethod':'getSubject_area', 'view':'lemill_browse_members'})), 
    342     # +++++++++++++++++++++++ 
    343     (('GroupBlog',),( 
    344     {'id':'browse_groups', 'title':'Groups', 'view':'lemill_titlecloud'}, 
    345     {'id':'tags', 'title':'Tags', 'getmethod':'getTags','view':'lemill_browse_groups'}, 
    346     {'id':'g_language', 'title':'Language', 'getmethod':'getLanguage_skills', 'view':'lemill_browse_groups'}, 
    347     {'id':'group_subject_area', 'title':'Subject area', 'getmethod':'getSubject_area', 'view':'lemill_browse_groups'})) 
    348     # +++++++++++++++++++++++ 
    349     ]}     
     293 
    350294 
    351295TEMPLATES = { 
     
    425369         
    426370DEFAULT_ICONS = { 
    427         'Piece':'piece', # shouldn't be called this way 
     371        'Piece':'images/default_media_piece.png', # shouldn't be called this way 
    428372        'PresentationMaterial':'images/default_presentation.png', 
    429373        'PILOTMaterial':'images/default_pilot.png', 
     
    509453    } 
    510454 
     455 
     456LANGUAGES=[('aa', 'Afar'), 
     457    ('ab', 'Abkhazian'), 
     458    ('af', 'Afrikaans'), 
     459    ('am', 'Amharic'), 
     460    ('ar', 'Arabic'), 
     461    ('as', 'Assamese'), 
     462    ('ay', 'Aymara'), 
     463    ('az', 'Azerbaijani'), 
     464    ('ba', 'Bashkir'), 
     465    ('be', 'Byelorussian (Belarussian)'), 
     466    ('bg', 'Bulgarian'), 
     467    ('bh', 'Bihari'), 
     468    ('bi', 'Bislama'), 
     469    ('bn', 'Bengali'), 
     470    ('bo', 'Tibetan'), 
     471    ('br', 'Breton'), 
     472    ('ca', 'Catalan'), 
     473    ('co', 'Corsican'), 
     474    ('cs', 'Czech'), 
     475    ('cy', 'Welsh'), 
     476    ('da', 'Danish'), 
     477    ('de', 'German'), 
     478    ('dz', 'Bhutani'), 
     479    ('el', 'Greek'), 
     480    ('en', 'English'), 
     481    ('eo', 'Esperanto'), 
     482    ('es', 'Spanish'), 
     483    ('et', 'Estonian'), 
     484    ('eu', 'Basque'), 
     485    ('fa', 'Persian'), 
     486    ('fi', 'Finnish'), 
     487    ('fj', 'Fiji'), 
     488    ('fo', 'Faroese'), 
     489    ('fr', 'French'), 
     490    ('fy', 'Frisian'), 
     491    ('ga', 'Irish (Irish Gaelic)'), 
     492    ('gd', 'Scots Gaelic (Scottish Gaelic)'), 
     493    ('gl', 'Galician'), 
     494    ('gn', 'Guarani'), 
     495    ('gu', 'Gujarati'), 
     496    ('gv', 'Manx Gaelic'), 
     497    ('ha', 'Hausa'), 
     498    ('he', 'Hebrew'), 
     499    ('hi', 'Hindi'), 
     500    ('hr', 'Croatian'), 
     501    ('hu', 'Hungarian'), 
     502    ('hy', 'Armenian'), 
     503    ('ia', 'Interlingua'), 
     504    ('id', 'Indonesian'), 
     505    ('ie', 'Interlingue'), 
     506    ('ik', 'Inupiak'), 
     507    ('is', 'Icelandic'), 
     508    ('it', 'Italian'), 
     509    ('iu', 'Inuktitut'), 
     510    ('ja', 'Japanese'), 
     511    ('jw', 'Javanese'), 
     512    ('ka', 'Georgian'), 
     513    ('kk', 'Kazakh'), 
     514    ('kl', 'Greenlandic'), 
     515    ('km', 'Cambodian'), 
     516    ('kn', 'Kannada'), 
     517    ('ko', 'Korean'), 
     518    ('ks', 'Kashmiri'), 
     519    ('ku', 'Kurdish'), 
     520    ('kw', 'Cornish'), 
     521    ('ky', 'Kirghiz'), 
     522    ('la', 'Latin'), 
     523    ('lb', 'Luxemburgish'), 
     524    ('ln', 'Lingala'), 
     525    ('lo', 'Laotian'), 
     526    ('lt', 'Lithuanian'), 
     527    ('lv', 'Latvian Lettish'), 
     528    ('mg', 'Malagasy'), 
     529    ('mi', 'Maori'), 
     530    ('mk', 'Macedonian'), 
     531    ('ml', 'Malayalam'), 
     532    ('mn', 'Mongolian'), 
     533    ('mo', 'Moldavian'), 
     534    ('mr', 'Marathi'), 
     535    ('ms', 'Malay'), 
     536    ('mt', 'Maltese'), 
     537    ('my', 'Burmese'), 
     538    ('na', 'Nauru'), 
     539    ('ne', 'Nepali'), 
     540    ('nl', 'Dutch'), 
     541    ('no', 'Norwegian'), 
     542    ('oc', 'Occitan'), 
     543    ('om', 'Oromo'), 
     544    ('or', 'Oriya'), 
     545    ('pa', 'Punjabi'), 
     546    ('pl', 'Polish'), 
     547    ('ps', 'Pashto'), 
     548    ('pt', 'Portuguese'), 
     549    ('qu', 'Quechua'), 
     550    ('rm', 'Rhaeto-Romance'), 
     551    ('rn', 'Kirundi'), 
     552    ('ro', 'Romanian'), 
     553    ('ru', 'Russian'), 
     554    ('rw', 'Kiyarwanda'), 
     555    ('sa', 'Sanskrit'), 
     556    ('sd', 'Sindhi'), 
     557    ('se', 'Northern Sami'), 
     558    ('sg', 'Sangho'), 
     559    ('sh', 'Serbo-Croatian'), 
     560    ('si', 'Singhalese'), 
     561    ('sk', 'Slovak'), 
     562    ('sl', 'Slovenian'), 
     563    ('sm', 'Samoan'), 
     564    ('sn', 'Shona'), 
     565    ('so', 'Somali'), 
     566    ('sq', 'Albanian'), 
     567    ('sr', 'Serbian'), 
     568    ('ss', 'Siswati'), 
     569    ('st', 'Sesotho'), 
     570    ('su', 'Sudanese'), 
     571    ('sv', 'Swedish'), 
     572    ('sw', 'Swahili'), 
     573    ('ta', 'Tamil'), 
     574    ('te', 'Telugu'), 
     575    ('tg', 'Tajik'), 
     576    ('th', 'Thai'), 
     577    ('ti', 'Tigrinya'), 
     578    ('tk', 'Turkmen'), 
     579    ('tl', 'Tagalog'), 
     580    ('tn', 'Setswana'), 
     581    ('to', 'Tonga'), 
     582    ('tr', 'Turkish'), 
     583    ('ts', 'Tsonga'), 
     584    ('tt', 'Tatar'), 
     585    ('tw', 'Twi'), 
     586    ('ug', 'Uigur'), 
     587    ('uk', 'Ukrainian'), 
     588    ('ur', 'Urdu'), 
     589    ('uz', 'Uzbek'), 
     590    ('vi', 'Vietnamese'), 
     591    ('vo', 'Volapuk'), 
     592    ('wo', 'Wolof'), 
     593    ('xh', 'Xhosa'), 
     594    ('yi', 'Yiddish'), 
     595    ('yo', 'Yorouba'), 
     596    ('za', 'Zhuang'), 
     597    ('zh', 'Chinese'), 
     598    ('zu', 'Zulu') 
     599] 
     600LANGUAGES.sort(lambda x,y:cmp(x[1], y[1])) 
     601# Put language neutral at the top. 
     602LANGUAGES.insert(0,('',u'Language neutral (site default)')) 
     603LANGUAGES_DICT=dict(LANGUAGES) 
     604  
  • trunk/skins/lemill/OAI-script.py

    r3045 r3052  
    22from Products.PythonScripts.standard import html_quote 
    33 
     4# this script tries to follow the OAI-protocol (http://www.openarchives.org/OAI/openarchivesprotocol.html) 
     5# oai_lom should be updated to v4.5... 
     6# http://lre.eun.org/sites/default/files/docs/LREMAPv4p5w.pdf  
    47 
    58context = context.content #So it can work as http://lemill.net/OAI-scipt 
     
    811portal_oai= 'oai:%s:' % '/'.join(portalURL.replace('http://', '').split('\\')).split('/')[0].split(':')[0] 
    912lt = context.lemill_tool 
     13t=lt.getTime() 
     14 
    1015 
    1116result=[] 
     
    7681sa['Cross-curricular education'] = (292, 'cross-curricular education') 
    7782 
    78  
     83# To increase speed we should cache user_id : nicename -mappings.  
     84name_cache={} 
     85def getNicename(user_id): 
     86    if user_id in name_cache: 
     87        return name_cache[user_id] 
     88    else: 
     89        userMD = context.getSearchObject(portal_type = 'MemberFolder', getState = ['public', 'draft'], getId = user_id) 
     90        if userMD: 
     91            userMD=userMD[0] 
     92            nn=userMD.getNicename 
     93        else: 
     94            nn=user_id 
     95        name_cache[user_id]=nn 
     96        return nn 
     97 
     98# also to increase speed we should have cache of collection ids 
     99d=lt.getTime() 
     100collection_cache=dict([(col.UID, col.getId) for col in context.getSearchObject(portal_type='Collection', getState='public')]) 
     101lt.dumpMe('building collection cache:' + str(lt.getTime()-d)) 
    79102 
    80103def IsThereResumptionTokenError(args): 
     
    160183    res = [] 
    161184    q = { 'targetUID': obj.UID, 'relationship':'relatesToContent'} 
    162     qres = obj.reference_catalog(q) 
     185    qres = context.reference_catalog(q) 
    163186    for q in qres: 
    164         rem = context.uid_catalog(UID=q.sourceUID) 
    165         if rem: 
    166             res.append(rem[0].id) 
     187        col_id=collection_cache.get(q.sourceUID, '') 
     188        if col_id: 
     189            res.append(col_id) 
    167190    return res 
    168191 
     
    188211    result.append(''.join(('<datestamp>',GenerateDateString(latestEditDate),'</datestamp>'))) 
    189212    for collectionID in getCollections(material): 
    190         result.append(''.join(('<setSpec>'+collectionID+'</setSpec>'))) 
     213        result.append(''.join(('<setSpec>',collectionID,'</setSpec>'))) 
    191214    result.append('</header>') 
    192215 
     
    216239def GenerateDublinCoreMetadata(obj): 
    217240    language = obj.Language or 'en' 
     241    if same_type(language, []): 
     242        language=language[0] 
    218243    result.append(''.join(('<oai_dc:dc xmlns:oai_dc="http://www.openarchives.org/OAI/2.0/oai_dc/" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.openarchives.org/OAI/2.0/oai_dc/ http://www.openarchives.org/OAI/2.0/oai_dc.xsd"><dc:title>',html_quote(obj.Title),'</dc:title>'))) 
    219244    creator = obj.Creator 
     
    231256    result.append('</oai_dc:dc>') 
    232257 
    233  
     258endUserRoleSources=['LOMv1.0', '', None] 
     259endUserRoles=['teacher', 'learner','',None] 
     260contextSourceTypes=['LREv3.0', 'LOMv1.0', '',None] 
     261contexts=[ 'continuing education','special education','higher education','compulsory education','pre-school','',None] 
    234262 
    235263def GenerateLOMMetadata(obj): 
    236264    language = obj.Language or 'en' 
     265    if same_type(language, []): 
     266        language=language[0] 
    237267    result.append('<lom xmlns="http://ltsc.ieee.org/xsd/LOM" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://ltsc.ieee.org/xsd/lomv1.0/lom.xsd http://ltsc.ieee.org/xsd/LOM">') 
    238268    result.append(''.join(('<general><identifier><catalog>lemill.net</catalog><entry>', str(obj.getId),':',obj.UID,'</entry></identifier><title><string language="',language,'">',html_quote(obj.Title),'</string></title><language>',language,'</language><description><string language="',language,'">',BodyTextToDescription(obj),'</string></description>')))  
     
    242272    result.append('</general><lifeCycle><version><string language="de">1.0</string></version><status><source>LOMv1.0</source><value>final</value></status>') 
    243273    for author in obj.listCreators: 
    244         userMD = context.getSearchObject(portal_type = 'MemberFolder', getState = ['public', 'draft'], getId = author) 
    245         if userMD: 
    246             userMD=userMD[0] 
    247             nn=userMD.getNicename 
     274        nn=getNicename(author) 
     275        if nn: 
    248276            try: 
    249277                names=nn.split(' ') 
     
    254282                nn='' 
    255283            result.append(''.join(('<contribute><role><source>LOMv1.0</source><value>author</value></role><entity>BEGIN:VCARD\nVERSION:3.0\nN:',html_quote(names),';;;\nFN:',html_quote(nn),'\nEND:VCARD</entity></contribute>'))) 
     284 
    256285    result.append(''.join(('</lifeCycle><metaMetadata><identifier><catalog>oai</catalog><entry>',obj.getId,'</entry></identifier><language>',language,'</language><metadataSchema>LREv3.0</metadataSchema></metaMetadata><technical><location>',obj.getURL(),'</location></technical><educational>'))) 
    257286    result.append('<learningResourceType><source>LREv3.0</source>') 
     
    262291    contextValues = [] 
    263292    for targetGroup in obj.getTarget_group: 
    264         age_range, role_source, role_value, context_source, context_value = tg.get(targetGroup,('','','','','')) 
    265         if age_range or role_source or role_value or context_source or context_value: 
     293        tg_val=tg.get(targetGroup, None) 
     294        if tg_val:  
     295            age_range, role_source, role_value, context_source, context_value = tg_val 
    266296            intendedEndUserRoleSources.append(role_source) 
    267297            intendedEndUserRoleValues.append(role_value) 
     
    270300            if age_range: 
    271301                result.append(''.join(('<typicalAgeRange><string language="x-t-lre">',age_range,'</string></typicalAgeRange>'))) 
    272     intendedEndUserRoleSource = GetMax(['LOMv1.0', '', None], intendedEndUserRoleSources) 
    273     intendedEndUserRoleValue = GetMax(['teacher', 'learner','',None], intendedEndUserRoleValues) 
    274     contextSource = GetMax(['LREv3.0', 'LOMv1.0', '',None], contextSources) 
    275     contextValue = GetMax([ 'continuing education','special education','higher education','compulsory education','pre-school','',None], contextValues) 
     302    intendedEndUserRoleSource = GetMax(endUserRoleSources, intendedEndUserRoleSources) 
     303    intendedEndUserRoleValue = GetMax(endUserRoles, intendedEndUserRoleValues) 
     304    contextSource = GetMax(contextSourceTypes, contextSources) 
     305    contextValue = GetMax(contexts, contextValues) 
    276306    if intendedEndUserRoleSource and intendedEndUserRoleValue: 
    277307        result.append(''.join(('<intendedEndUserRole><source>',intendedEndUserRoleSource,'</source><value>', intendedEndUserRoleValue,'</value></intendedEndUserRole>'))) 
     
    288318        result.append('</taxonPath></classification>') 
    289319    result.append('</lom>') 
    290  
    291320 
    292321 
     
    405434            query['UID']=getUidsFromCollection(args['set'])        
    406435            restoken.append('s%s' % args['set']) 
    407  
    408     results=context.getSearchObject(**query)     
     436    results=context.getSearchObject(**query) 
    409437    if start>len(results): 
    410438        result.pop() 
    411439        raise ERROR_badResumptionToken 
    412440    end=start+1000 
    413      
    414     for material in results[start:end]: 
     441    for material in results[start:end]:  
    415442        try: 
    416             wrapper(material, method=method) 
     443            wrapper(material, method=method) # wrapper is usually GetRecord or GenerateOneHeader 
    417444        except UnicodeDecodeError: 
    418445            raise 'Unicode decode problem with resource %s' % str(material.getId) 
     446    lt.dumpMe('Contains %s results' % len(results))  
    419447    if not results: 
    420448        result.pop() 
     
    465493result.append('>%s/OAI-script</request>' % context.aq_parent.absolute_url()) 
    466494 
    467 verb_methods={'GetRecord':GetOneRecord, 'Identify':GenerateIdentify, 'ListIdentifiers':GenerateHeaders, 'ListMetadataFormats':ListMetadataFormats, 'ListRecords':GenerateRecords,'ListSets':ListCollections} 
    468495 
    469496try: 
     
    476503 
    477504    result.append('<%s>' % verb) 
    478     verb_methods[verb]() 
     505    if verb=='GetRecord': 
     506        GetOneRecord() 
     507    elif verb=='Identify': 
     508        GenerateIdentify() 
     509    elif verb=='ListIdentifiers': 
     510        GenerateHeaders() 
     511    elif verb=='ListMetadataFormats': 
     512        ListMetadataFormats() 
     513    elif verb=='ListRecords': 
     514        GenerateRecords() 
     515    elif verb=='ListSets': 
     516        ListCollections() 
    479517    result.append('</%s>' % verb) 
    480518 
     
    497535 
    498536result.append('</OAI-PMH>') 
    499  
     537lt.dumpMe('Building this took:'+str(lt.getTime()-t)) 
    500538return u'\n'.join([r.decode('utf-8') for r in result]).encode('utf-8') 
  • trunk/skins/lemill/batch_macros.pt

    r2238 r3052  
    55 
    66<!-- Navigation --> 
    7 <div class="listingBar" 
    8      metal:define-macro="navigation" 
    9      tal:define="request request|here/request|container/request|nothing; 
    10                  batch batch|nothing; 
    11                  template_id template_id|template/getId; 
    12                  mq python:modules['ZTUtils'].make_query; 
    13                  url batch_base_url | python: test(template_id=='lemill_search_results', '%s/%s' % (here_url, template_id), here_url); 
    14                  currentpage batch/pagenumber; 
    15                  " 
    16      tal:condition="python: batch.next or  batch.previous"> 
    17 <!-- TODO tesdal needs to have a look at these 
    18     <metal:rellinks fill-slot="rel_slot"> 
    19         <link rel="first" href="" title="First page" tal:attributes="href string:author" /> 
    20         <link rel="last" href="" title="Last page" tal:attributes="href string:author" /> 
    21         <link rel="previous" href="" title="Previous page" tal:attributes="href string:author" /> 
    22         <link rel="next" href="" title="Next page" tal:attributes="href string:author" /> 
    23     </metal:rellinks> 
    24 --> 
    25  
    26     <span class="previous" 
    27       tal:define="p batch/previous | nothing" 
    28       tal:condition="p"> 
    29         <a href="" 
    30            tal:attributes="href python: '%s?%s' % (url , mq( request.form, {batch.b_start_str:p.first}))"> 
    31            &laquo; 
    32            <span i18n:translate="batch_previous_x_items" tal:omit-tag=""> 
    33                Previous 
    34                <span i18n:name="number" tal:omit-tag="" tal:content="p/length">n</span> 
    35                items 
    36            </span> 
    37         </a> 
    38     </span> 
    39  
    40     <span class="next" 
    41       tal:define="n batch/next | nothing" 
    42       tal:condition="n"> 
    43         <a href="" 
    44            tal:attributes="href python: '%s?%s' % (url , mq( request.form, {batch.b_start_str:n.first}))"> 
    45            <span i18n:translate="batch_next_x_items" tal:omit-tag=""> 
    46                Next 
    47                <span i18n:name="number" tal:omit-tag="" tal:content="n/length">n</span> 
    48                items 
    49            </span> 
    50            &raquo; 
    51         </a> 
    52     </span> 
    53  
     7<div class="listingBar" metal:define-macro="navigation" tal:define="url_slot context/portal_catalog/batchBaseUrl" tal:condition="python: batch.nextlist or batch.prevlist"> 
     8    <span class="previous" tal:define="p batch/prevlist | nothing" tal:condition="p"><a href="" tal:attributes="href python: url_slot % ((p[-1]-1)*30)">&laquo; <span i18n:translate="batch_previous_x_items" tal:omit-tag=""> Previous <span i18n:name="number" tal:omit-tag="">30</span> items </span></a></span> 
     9    <span class="next" tal:define="n batch/nextlist | nothing" tal:condition="n"><a href="" tal:attributes="href python: url_slot % ((n[0]-1)*30)"><span i18n:translate="batch_next_x_items" tal:omit-tag="">Next <span i18n:name="number" tal:omit-tag="" >30</span> items </span> &raquo;</a></span> 
    5410    <!-- Link to first --> 
    55     <span tal:condition="python: 1 not in batch.navlist"> 
    56         <a href="" 
    57            tal:attributes="href python: '%s?%s' % (url, batch.pageurl(request.form,1));">1</a> 
    58         <span tal:condition="python: 2 not in (batch.prevlist or batch.leapback)" 
    59               tal:omit-tag=""> 
    60            ... 
    61         </span> 
    62     </span> 
    63  
    64     <!-- Pagelist with quantum leap links to previous pages for quick navigation --> 
    65     <span tal:repeat="linklist python:batch.navurls(request.form, batch.leapback)" 
    66           tal:condition="batch/leapback" 
    67           tal:omit-tag="" > 
    68         <a href="" 
    69            tal:define="page python:linklist[0]; 
    70                        query python:linklist[1];" 
    71            tal:content="page" 
    72            tal:attributes="href python: '%s?%s' % (url,query)" > 
    73         </a> 
    74         ... 
    75     </span> 
    76  
     11    <span tal:condition="python: 1 not in batch.navlist"><a href="" tal:attributes="href python: url_slot % 0">1</a><span tal:condition="python: 2 not in batch.prevlist" tal:omit-tag=""> ... </span></span> 
    7712    <!-- Pagelist with links to previous pages for quick navigation --> 
    78     <span tal:repeat="linklist python:batch.prevurls(request.form)" 
    79           tal:condition="batch/prevlist" 
    80           tal:omit-tag="" > 
    81         <a href="" 
    82            tal:define="page python:linklist[0]; 
    83                        query python:linklist[1];" 
    84            tal:content="page" 
    85            tal:attributes="href python: '%s?%s' % (url,query)" > 
    86         </a> 
    87     </span> 
    88  
     13    <span tal:repeat="page batch/prevlist" tal:omit-tag="" ><a href="" tal:content="page" tal:attributes="href python: url_slot % ((page-1)*30)" >3</a></span> 
    8914    <!-- Current page --> 
    90     <span tal:condition="batch/navlist" 
    91           tal:omit-tag=""> 
    92         [<span tal:content="batch/pagenumber">Current page number</span>] 
    93     </span> 
    94  
     15    <span tal:condition="batch/navlist" tal:omit-tag="">[<span tal:content="batch/pagenumber">Current page number</span>]</span> 
    9516    <!-- Pagelist with links to next pages for quick navigation --> 
    96     <span tal:repeat="linklist python:batch.nexturls(request.form)" 
    97           tal:condition="batch/nextlist" 
    98           tal:omit-tag="" > 
    99         <a href="" 
    100            tal:define="page python:linklist[0]; 
    101                        query python:linklist[1];" 
    102            tal:content="page" 
    103            tal:attributes="href python: '%s?%s' % (url,query)" > 
    104         </a> 
    105     </span> 
    106  
    107     <!-- Pagelist with quantum leap links to next pages for quick navigation --> 
    108     <span tal:repeat="linklist python:batch.navurls(request.form, batch.leapforward)" 
    109           tal:condition="batch/leapforward" 
    110           tal:omit-tag="" > 
    111         ... 
    112         <a href="" 
    113            tal:define="page python:linklist[0]; 
    114                        query python:linklist[1];" 
    115            tal:content="page" 
    116            tal:attributes="href python: '%s?%s' % (url,query)" > 
    117         </a> 
    118     </span> 
    119  
     17    <span tal:repeat="page batch/nextlist" tal:omit-tag="" ><a href="" tal:content="page" tal:attributes="href python: url_slot % ((page-1)*30)" ></a></span> 
    12018    <!-- Link to last --> 
    121     <span tal:condition="python:batch.numpages not in batch.navlist"> 
    122         <span tal:condition="python: batch.numpages - 1 not in (batch.nextlist or batch.leapforward)" 
    123               tal:omit-tag=""> 
    124         ... 
    125         </span> 
    126         <a href="" 
    127            tal:attributes="href python: '%s?%s' % (url,batch.pageurl(request.form,batch.numpages));" 
    128            tal:content="batch/numpages">3457</a> 
    129     </span> 
    130  
     19    <span tal:condition="python:batch.numpages not in batch.navlist"><span tal:condition="python: batch.numpages - 1 not in batch.nextlist" tal:omit-tag=""> ...</span><a href="" tal:attributes="href python: url_slot % ((batch.numpages-1)*30)" tal:content="batch/numpages">3457</a></span> 
    13120</div> 
    13221 
    133 <!-- Navigation in portfolios --> 
    134 <div class="listingBar" 
    135      metal:define-macro="portfolio_navigation" 
    136      tal:define="request request|here/request|container/request|nothing; 
    137                  batch batch|nothing; 
    138                  mq python:modules['ZTUtils'].make_query; 
    139                  url string:${memberfolder_url}/portfolio; 
    140                  currentpage batch/pagenumber; 
    141                  " 
    142      tal:condition="python: batch.next or  batch.previous"> 
    143 <!-- TODO tesdal needs to have a look at these 
    144     <metal:rellinks fill-slot="rel_slot"> 
    145         <link rel="first" href="" title="First page" tal:attributes="href string:author" /> 
    146         <link rel="last" href="" title="Last page" tal:attributes="href string:author" /> 
    147         <link rel="previous" href="" title="Previous page" tal:attributes="href string:author" /> 
    148         <link rel="next" href="" title="Next page" tal:attributes="href string:author" /> 
    149     </metal:rellinks> 
    150 --> 
    151  
    152     <span class="previous" 
    153       tal:define="p batch/previous | nothing" 
    154       tal:condition="p"> 
    155         <a href="" 
    156            tal:attributes="href python: '%s?%s' % (url , mq( request.form, {batch.b_start_str:p.first}))"> 
    157            &laquo; 
    158            <span i18n:translate="batch_previous_x_items" tal:omit-tag=""> 
    159                Previous 
    160                <span i18n:name="number" tal:omit-tag="" tal:content="p/length">n</span> 
    161                items 
    162            </span> 
    163         </a> 
    164     </span> 
    165  
    166     <span class="next" 
    167       tal:define="n batch/next | nothing" 
    168       tal:condition="n"> 
    169         <a href="" 
    170            tal:attributes="href python: '%s?%s' % (url , mq( request.form, {batch.b_start_str:n.first}))"> 
    171            <span i18n:translate="batch_next_x_items" tal:omit-tag=""> 
    172                Next 
    173                <span i18n:name="number" tal:omit-tag="" tal:content="n/length">n</span> 
    174                items 
    175            </span> 
    176            &raquo; 
    177         </a> 
    178     </span> 
    179  
    180     <!-- Link to first --> 
    181     <span tal:condition="python: 1 not in batch.navlist"> 
    182         <a href="" 
    183            tal:attributes="href python: '%s?%s' % (url, batch.pageurl(request.form,1));">1</a> 
    184         <span tal:condition="python: 2 not in (batch.prevlist or batch.leapback)" 
    185               tal:omit-tag=""> 
    186            ... 
    187         </span> 
    188     </span> 
    189  
    190     <!-- Pagelist with quantum leap links to previous pages for quick navigation --> 
    191     <span tal:repeat="linklist python:batch.navurls(request.form, batch.leapback)" 
    192           tal:condition="batch/leapback" 
    193           tal:omit-tag="" > 
    194         <a href="" 
    195            tal:define="page python:linklist[0]; 
    196                        query python:linklist[1];" 
    197            tal:content="page" 
    198            tal:attributes="href python: '%s?%s' % (url,query)" > 
    199         </a> 
    200         ... 
    201     </span> 
    202  
    203     <!-- Pagelist with links to previous pages for quick navigation --> 
    204     <span tal:repeat="linklist python:batch.prevurls(request.form)" 
    205           tal:condition="batch/prevlist" 
    206           tal:omit-tag="" > 
    207         <a href="" 
    208            tal:define="page python:linklist[0]; 
    209                        query python:linklist[1];" 
    210            tal:content="page" 
    211            tal:attributes="href python: '%s?%s' % (url,query)" > 
    212         </a> 
    213     </span> 
    214  
    215     <!-- Current page --> 
    216     <span tal:condition="batch/navlist" 
    217           tal:omit-tag=""> 
    218         [<span tal:content="batch/pagenumber">Current page number</span>] 
    219     </span> 
    220  
    221     <!-- Pagelist with links to next pages for quick navigation --> 
    222     <span tal:repeat="linklist python:batch.nexturls(request.form)" 
    223           tal:condition="batch/nextlist" 
    224           tal:omit-tag="" > 
    225         <a href="" 
    226            tal:define="page python:linklist[0]; 
    227                        query python:linklist[1];" 
    228            tal:content="page" 
    229            tal:attributes="href python: '%s?%s' % (url,query)" > 
    230         </a> 
    231     </span> 
    232  
    233     <!-- Pagelist with quantum leap links to next pages for quick navigation --> 
    234     <span tal:repeat="linklist python:batch.navurls(request.form, batch.leapforward)" 
    235           tal:condition="batch/leapforward" 
    236           tal:omit-tag="" > 
    237         ... 
    238         <a href="" 
    239            tal:define="page python:linklist[0]; 
    240                        query python:linklist[1];" 
    241            tal:content="page" 
    242            tal:attributes="href python: '%s?%s' % (url,query)" > 
    243         </a> 
    244     </span> 
    245  
    246     <!-- Link to last --> 
    247     <span tal:condition="python:batch.numpages not in batch.navlist"> 
    248         <span tal:condition="python: batch.numpages - 1 not in (batch.nextlist or batch.leapforward)" 
    249               tal:omit-tag=""> 
    250         ... 
    251         </span> 
    252         <a href="" 
    253            tal:attributes="href python: '%s?%s' % (url,batch.pageurl(request.form,batch.numpages));" 
    254            tal:content="batch/numpages">3457</a> 
    255     </span> 
    256  
    257 </div> 
    25822 
    25923</body> 
  • trunk/skins/lemill/browse_macros.pt

    r3044 r3052  
    1616</tal:rss_macro> 
    1717 
    18  
    19 <tal:tagcloud metal:define-macro="direct_linking_tagcloud"> 
    20  
    21     <div tal:condition="not: wordtuples"> 
    22         <p><strong i18n:domain="plone" i18n:translate="description_no_results_found">No results were found.</strong></p> 
    23     </div> 
    24  
    25     <fieldset tal:condition="wordtuples"> 
    26      
    27     <table class="keyword_list"> 
    28         <tr> 
    29             <td>  
    30             <tal:taggy repeat="wordinfo wordtuples"> 
    31             <tal:taggyvalues define="sort_name python:wordinfo[0]; 
    32                     tagsize python:wordinfo[1]; 
    33                     obj_url python:wordinfo[2]; 
    34                     tag_value python:wordinfo[3]; 
    35                     nicename python:wordinfo[4]; 
    36                     "> 
    37             <span tal:attributes="class string:size$tagsize"> 
    38             <a tal:attributes="href obj_url" tal:content="nicename"/> 
    39             </span> 
    40             </tal:taggyvalues>  
    41             <tal:comma tal:condition="not: repeat/wordinfo/end">, </tal:comma> 
    42             </tal:taggy>  
    43             </td> 
    44         </tr> 
    45         </table> 
    46     </fieldset> 
    47  
    48 </tal:tagcloud> 
    49  
    50 <tal:tagcloud2 metal:define-macro="forwarding_tagcloud"> 
    51  
    52     <div tal:condition="not: wordtuples"> 
    53         <p><strong i18n:domain="plone" i18n:translate="description_no_results_found">No results were found.</strong></p> 
    54     </div> 
    55  
    56     <fieldset tal:condition="wordtuples"> 
    57      
    58     <table class="keyword_list" tal:define="nice_method_name python:context.script_nice_name_for_browse_method(context.getmethod); 
    59 "> 
    60         <tr> 
    61             <td>  
    62             <tal:taggy repeat="wordinfo wordtuples"> 
    63             <tal:taggyvalues define="sort_name python:wordinfo[0]; 
    64                     tagsize python:wordinfo[1]; 
    65                     obj_url python:wordinfo[2]; 
    66                     tag_value python:wordinfo[3]; 
    67                     nicename python:wordinfo[4]; 
    68                     "> 
    69             <span tal:attributes="class string:size$tagsize"> 
    70             <a tal:attributes="href python: '%s?%s=%s' % (here_url, nice_method_name, tag_value)" tal:content="nicename" i18n:translate="" /> 
    71             </span> 
    72             </tal:taggyvalues>  
    73             <tal:comma tal:condition="not: repeat/wordinfo/end">, </tal:comma> 
    74             </tal:taggy>  
    75             </td> 
    76         </tr> 
    77         </table> 
    78     </fieldset> 
    79  
    80 </tal:tagcloud2> 
    81  
    82 <tal:checkbox_macro metal:define-macro="checkbox_macro"> 
    83     <input type="checkbox" tal:attributes="name selection_type;  
    84     value python:selectables.get(selection_type, [('','')])[0][1];  
    85     checked python: test(form.get(selection_type, default_checked), 1, 0);" /> 
    86 </tal:checkbox_macro> 
    87  
    88  
    89 <tal:select_macro metal:define-macro="select_macro"> 
    90     <select tal:attributes="tabindex tabindex/next; name selection_type"  
    91     tal:define="value_is_set python:form.has_key(selection_type); 
    92         values python:selectables[selection_type]; 
    93         current_value python:form.get(selection_type,None)"> 
    94         <option value="" i18n:translate="" tal:content="default_all | string:All">All</option> 
    95             <tal:has_value condition="value_is_set"> 
    96             <tal:loop repeat="item values"> 
    97                 <option tal:attributes="value python:item[1]; selected python:current_value==item[1]"> 
    98                 <span tal:content="python:str(item[0])" i18n:translate="" /> 
    99                 (<span tal:replace="python:item[2]"/>) 
    100                 </option> 
    101             </tal:loop> 
    102             </tal:has_value> 
    103             <tal:has_not_value condition="not:value_is_set" repeat="item values">             
    104             <option  
    105                 tal:attributes="value python:str(item[1])"> 
    106                 <span tal:content="python:str(item[0])" i18n:translate="" /> 
    107                 (<span tal:replace="python:str(item[2])"/>) 
    108             </option> 
    109             </tal:has_not_value>                 
    110     </select> 
    111 </tal:select_macro> 
     18<tal:options metal:define-macro="browse_options"> 
     19<div class="browse_options portlet grid"> 
     20    <form name="browse" 
     21           method="POST" 
     22           action="browse" tal:define="form request/form; 
     23           global results request/results | python: here.portal_catalog.browsingSearch(REQUEST=request); 
     24           d python:here.portal_catalog.createBrowsingOptions(REQUEST=request, results=results); 
     25           section context/getSectionFolder | nothing; 
     26           url_base section/absolute_url | portal_url; 
     27           cloud_url string:$url_base/cloud; 
     28           lang_filter d/lang_filter;" 
     29           tal:attributes="action string:$url_base/browse"> 
     30     <p tal:condition="d/do_languages"><a href="" tal:attributes="href string:$cloud_url?base=language" i18n:translate="">Language</a><br/> 
     31        <select tal:attributes="tabindex tabindex/next; disabled d/lang_disabled" name="language" onchange="this.form.submit()"> 
     32            <optgroup><tal:loop repeat="item d/common_languages"><option tal:attributes="value python:item[0]; selected python:item[2]"><span tal:replace="python:str(item[1])" /><tal:counter condition="python:item[3]"> (<span tal:replace="python:item[3]"/>)</tal:counter></option></tal:loop></optgroup> 
     33            <optgroup label="-------------"><tal:loop repeat="item d/rare_languages"><option tal:attributes="value python:item[0]; selected python:item[2]"><span tal:content="python:str(item[1])" /><tal:counter condition="python:item[3]"> (<span tal:replace="python:item[3]"/>)</tal:counter></option></tal:loop></optgroup> 
     34        </select> 
     35     </p>          
     36     <p tal:condition="d/do_subject_areas"><a href="" tal:attributes="href string:$cloud_url?${lang_filter}base=subject_area" i18n:translate="">Subject area</a><br/> 
     37        <select tal:attributes="tabindex tabindex/next; disabled d/subjs_disabled" name="subject_area" onchange="this.form.submit()"> 
     38            <tal:loop repeat="item d/subject_area"><option tal:attributes="value python:item[0]; selected python:item[2]"><span tal:content="python:str(item[1])" i18n:translate="" tal:omit-tag=""/><tal:counter condition="python:item[3]"> (<span tal:replace="python:item[3]"/>)</tal:counter></option></tal:loop> 
     39        </select> 
     40     </p> 
     41     <p tal:condition="d/do_target_groups"><a href="" tal:attributes="href string:$cloud_url?${lang_filter}base=target_group" i18n:translate="">Target group</a><br/> 
     42        <select tal:attributes="tabindex tabindex/next; disabled d/targs_disabled" name="target_group" onchange="this.form.submit()"> 
     43            <tal:loop repeat="item d/target_group"><option tal:attributes="value python:item[0]; selected python:item[2]"><span tal:content="python:str(item[1])" i18n:translate="" tal:omit-tag=""/><tal:counter condition="python:item[3]"> (<span tal:replace="python:item[3]"/>)</tal:counter></option></tal:loop> 
     44        </select> 
     45     </p> 
     46     <p tal:condition="d/do_types"><span i18n:translate="">Type</span><br/> 
     47        <select tal:attributes="tabindex tabindex/next" name="type" onchange="this.form.submit()"> 
     48            <tal:loop repeat="item d/type"><option tal:attributes="value python:item[0]; selected python:item[2]"><span tal:content="python:str(item[1])" i18n:translate="" tal:omit-tag=""/><tal:counter condition="python:item[3]"> (<span tal:replace="python:item[3]"/>)</tal:counter></option></tal:loop> 
     49        </select> 
     50     </p> 
     51     <p tal:condition="d/do_edited"><span i18n:translate="">Date</span><br/> 
     52        <select tal:attributes="tabindex tabindex/next" name="edited" onchange="this.form.submit()"> 
     53            <tal:loop repeat="item d/edited"><option tal:attributes="value python:item[0]; selected python:item[2]"><span tal:content="python:str(item[1])" i18n:translate="" tal:omit-tag=""/></option></tal:loop> 
     54        </select> 
     55     </p> 
     56     <input type="hidden" name="state" value="" tal:attributes="value d/state" /> 
     57     <input type="hidden" name="author" value="" tal:attributes="value d/author" /> 
     58     <input type="hidden" name="form.submitted" value="1" /> 
     59     <p tal:condition="d/do_tags"><a href="" tal:attributes="href string:$cloud_url?${lang_filter}base=tags" i18n:translate="label_tag_cloud">tag cloud</a></p> 
     60  </form> 
     61</div> 
     62</tal:options> 
    11263 
    11364 
  • trunk/skins/lemill/getSectionColors.py

    r3014 r3052  
    3030    light= '#ccdd77' 
    3131 
    32 return """#tb-portal-header, #tb-portal-footer, #tb-portal-globalnav .selected, .tb-portlet, .portalMessage, h1, h2, h3, h4, h5, h6 { 
     32return """ .selected, .portlet, .portalMessage, h1, h2, h3, h4, h5, h6 { 
    3333    border-color: %(d)s;} 
    3434.portlet-title, .logo { background-color: %(d)s; } 
  • trunk/skins/lemill/getSectionFromURL.py

    r3005 r3052  
    88##title=Returns section name (first part of URL) to the body tag 
    99## 
    10 lemill_sections = ('content', 'methods', 'tools', 'community') 
    1110contentPath = context.portal_url.getRelativeContentPath(context) 
    1211if not contentPath: 
    13     return "content" 
     12    return "" 
    1413else: 
    1514    # Additional check in case some pages are shown outside the section context 
    16     if contentPath[0] in lemill_sections: 
     15    if contentPath[0] in ('content', 'methods', 'tools', 'community'): 
    1716        return contentPath[0] 
    1817    else: 
    19         return "content" 
     18        return "" 
  • trunk/skins/lemill/header.pt

    r3045 r3052  
    1313    <script type="text/javascript" tal:attributes="src string:$portal_url/jquery.js"></script> 
    1414    <script type="text/javascript" tal:attributes="src string:$portal_url/master.js"></script> 
    15     <style type="text/css" media="all" tal:content="string:@import url($portal_url/master.css);">@import "master.css";</style> 
    1615    <style type="text/css" media="all" tal:content="string:@import url($portal_url/lemill_grid.css);">@import "lemill_grid.css";</style> 
    1716    <style type="text/css" media="all" tal:content="here/getSectionColors" /> 
    18     <!-- Internet Explorer CSS Fixes --> 
    19     <tal:iefixstart replace="structure string:&lt;!--[if IE]&gt;" /> 
    20         <style type="text/css" media="all" tal:condition="exists: portal/IEFixesLeMill.css" 
    21                tal:content="string:@import url($portal_url/IEFixesLeMill.css);"> 
    22         </style> 
    23     <tal:iefixend replace="structure string:&lt;![endif]--&gt;" /> 
    2417    <link rel="shortcut icon" type="image/x-icon" tal:attributes="href string:$portal_url/favicon.ico" /> 
    2518    <link rel="home" 
  • trunk/skins/lemill/lemill_activities_view.pt

    r3000 r3052  
    55<body> 
    66 
    7 <div metal:fill-slot="main" style="width:100%"> 
    8    <span tal:define="samples context/getSamples" tal:condition="samples" tal:omit-tag=""> 
    9     <h1 i18n:translate="heading_featured_methods">Featured methods</h1> 
    10     <div metal:define-macro="featured"> 
    11     <table border="0" cellpadding="0" cellspacing="4" width="550"> 
    12         <tr> 
    13             <td class="coverimagecell" tal:repeat="obj samples"> 
    14                 <a href="#" title="Cover image" tal:attributes="href string:${obj/getURL}/view; title obj/Title | nothing;"> 
    15                     <img alt="Cover image" tal:attributes="src string:${obj/getURL}/coverImage; alt obj/Title | nothing;" src="images/default_method.png" /></a> 
    16             </td> 
    17         </tr> 
    18         <tr> 
    19             <td class="captioncell" tal:repeat="obj samples"> 
    20                 <a href="#"  tal:attributes="href string:${obj/getURL}/view" tal:content="python:context.lemill_tool.shortenTitle(obj.Title, 48)">PLACEHOLDER</a> 
    21             </td> 
    22         </tr> 
    23     </table> 
    24     </div>                                                                 
     7<metal:main fill-slot="main"> 
     8    <div class="title grid"> 
     9        <h1 i18n:translate="heading_featured_methods">Featured methods</h1> 
     10    </div> 
     11    <div class="clear"></div> 
     12   <span tal:define="samples here/getSamples" tal:condition="samples" tal:omit-tag="">  
     13       <tal:coverimages repeat="obj samples">    
     14         <div class="methods_border featured_item grid" tal:define="first repeat/obj/start; last repeat/obj/end;" tal:attributes="style  python:test(first, 'margin-left:0', test(last, 'margin-right:0', ''));"> 
     15            &nbsp;<a href="#" title="Cover image" tal:attributes="href obj/getURL; title obj/Title | nothing;">              
     16              <img alt="Cover image" valign="middle" tal:attributes="src string:${obj/getURL}/coverImage; alt obj/Title | nothing;" src="images/default_learningresource.png" /> 
     17            </a>&nbsp; 
     18         </div> 
     19      </tal:coverimages> 
     20      <div class="clear"></div> 
     21      <tal:titles repeat="obj samples"> 
     22        <div class="resource_title grid" tal:define="first repeat/obj/start; last repeat/obj/end;" tal:attributes="style python:test(first, 'margin-left:0', test(last, 'margin-right:0', ''));"> 
     23            <a href="#"  tal:attributes="href obj/getURL" tal:content="python:context.lemill_tool.shortenTitle(obj.Title, 48)">PLACEHOLDER</a> 
     24        </div> 
     25      </tal:titles> 
    2526   </span> 
    26     <h1 i18n:translate="heading_browser_methods">Browse methods</h1>     
    27     <ul> 
    28         <li> 
    29             <a i18n:translate="label_browse_by_language" href="language" class="byTextsFont">By language</a>: 
    30             <span tal:repeat="result context/top3languages"> 
    31                 <a href="" tal:attributes="href python:'language?language='+here.url_quote(result)" tal:content="python:here.script_getPrettyLanguage(result)">PLACEHOLDER</a>, 
    32             </span> 
    33             <a href="language">...</a> 
    34         </li>         
    35         <li> 
    36             <a i18n:translate="label_browse_by_title_cloud" href="browse_methods" class="byTextsFont">By title cloud</a> 
    37         </li> 
    38         <li> 
    39             <a i18n:translate="label_browse_by_tags" href="tags" class="byTextsFont">By tags</a>: 
    40             <span tal:repeat="result context/top3tags"> 
    41                 <a href="" tal:attributes="href python:'tags?tag='+here.url_quote(result)" tal:content="result">PLACEHOLDER</a>, 
    42             </span> 
    43             <a href="tags">...</a> 
    44         </li> 
    45     </ul> 
    46 </div> 
     27 
     28 
     29  <div class="browse_links grid" tal:define="lang_filter context/getLanguageFilter"> 
     30    <dl> 
     31        <dt><a i18n:translate="label_languages" href="cloud?base=language">Languages</a></dt> 
     32        <dd><span tal:repeat="result context/top3languages | nothing"> 
     33            <a href="" tal:attributes="href python:'language?language=%s' % here.url_quote(result)" tal:content="python:here.script_getPrettyLanguage(result)">PLACEHOLDER</a>, </span><a href="rebuildTop3s" tal:condition="context/amIManager">( rebuild top results )</a><a href="cloud?base=language">...</a> 
     34        </dd> 
     35        <dt><a i18n:translate="label_popularity" href="" tal:attributes="href string:cloud?${lang_filter}base=title">Popularity</a></dt> 
     36        <dd></dd> 
     37 
     38        <dt><a i18n:translate="label_tags" href=""  tal:attributes="href string:cloud?${lang_filter}base=tags">Tags</a></dt> 
     39        <dd><span tal:repeat="result python:context.portal_catalog.getTopFive(results,'getTags', 'browse?%stags=' % lang_filter)"> 
     40                <a href="" tal:attributes="href python:result[1]" tal:content="python:result[0]">PLACEHOLDER</a>, 
     41            </span><a href="" tal:attributes="href string:cloud?${lang_filter}base=tags">...</a> 
     42        </dd> 
     43    </dl> 
     44    </div> 
     45</metal:main> 
    4746</body> 
    4847</html> 
    4948 
     49 
  • trunk/skins/lemill/lemill_community_view.pt

    r3024 r3052  
    55<body> 
    66 
    7 <div metal:fill-slot="main" style="width:100%"> 
    8    <span tal:define="samples here/getSamples" tal:condition="samples" tal:omit-tag="">    
    9     <h1 i18n:translate="heading_featured_people">Featured people</h1> 
    10     <table border="0" cellpadding="0" cellspacing="4" width="550"> 
    11         <tr> 
    12             <td class="coverimagecell" tal:repeat="obj samples"> 
    13                 <a href="#" title="Cover image" tal:attributes="href string:${obj/getURL}/view; title obj/Title | nothing;"> 
    14                     <img alt="Cover image" tal:attributes="src string:${obj/getURL}/coverImage; alt obj/Title | nothing;" src="images/default_learningresource.png" /></a> 
    15             </td> 
    16         </tr> 
    17         <tr> 
    18             <td class="captioncell" tal:repeat="obj samples"> 
    19                 <a href="#"  tal:attributes="href string:${obj/getURL}/view" tal:content="python:context.lemill_tool.shortenTitle(obj.Title, 48)">PLACEHOLDER</a> 
    20             </td> 
    21         </tr> 
    22     </table> 
    23    </span>    
     7<metal:main fill-slot="main"> 
     8    <div class="title grid"> 
     9       <h1 i18n:translate="heading_featured_groups">Featured groups</h1> 
     10    </div> 
     11    <div class="clear"></div> 
     12   <span tal:define="samples here/getSamples" tal:condition="samples" tal:omit-tag="">  
     13       <tal:coverimages repeat="obj samples">    
     14         <div class="community_border featured_item grid" tal:define="first repeat/obj/start; last repeat/obj/end;" tal:attributes="style  python:test(first, 'margin-left:0', test(last, 'margin-right:0', ''));"> 
     15            &nbsp;<a href="#" title="Cover image" tal:attributes="href obj/getURL; title obj/Title | nothing;">              
     16              <img alt="Cover image" valign="middle" tal:attributes="src string:${obj/getURL}/coverImage; alt obj/Title | nothing;" src="images/default_learningresource.png" /> 
     17            </a>&nbsp; 
     18         </div> 
     19      </tal:coverimages> 
     20      <div class="clear"></div> 
     21      <tal:titles repeat="obj samples"> 
     22        <div class="resource_title grid" tal:define="first repeat/obj/start; last repeat/obj/end;" tal:attributes="style python:test(first, 'margin-left:0', test(last, 'margin-right:0', ''));"> 
     23            <a href="#"  tal:attributes="href obj/getURL" tal:content="python:context.lemill_tool.shortenTitle(obj.Title, 48)">PLACEHOLDER</a> 
     24        </div> 
     25      </tal:titles> 
     26   </span> 
     27 
    2428    <h1 i18n:translate="heading_browse_people">Browse people</h1>     
    2529    <ul> 
     
    103107           </table> 
    104108       </tal:group_recent_threads>     
    105 </div>     
    106   </body> 
     109</metal:main> 
     110 </body> 
    107111</html> 
    108112 
  • trunk/skins/lemill/lemill_content_view.pt

    r3024 r3052  
    55<body> 
    66 
    7 <div metal:fill-slot="main" style="width:100%"> 
    8     <h1 i18n:translate="heading_featured_content">Featured content</h1> 
    9    <span tal:define="samples here/getSamples" tal:condition="samples" tal:omit-tag=""> 
    10     <table border="0" cellpadding="0" cellspacing="4" width="550"> 
    11         <tr> 
    12             <td class="coverimagecell" tal:repeat="obj samples"> 
    13                 <a href="#" title="Cover image" tal:attributes="href string:${obj/getURL}/view; title obj/Title | nothing;"> 
    14                     <img alt="Cover image" tal:attributes="src string:${obj/getURL}/coverImage; alt obj/Title | nothing;" src="images/default_learningresource.png" /></a> 
    15             </td> 
    16         </tr> 
    17         <tr> 
    18             <td class="captioncell" tal:repeat="obj samples"> 
    19                 <a href="#"  tal:attributes="href string:${obj/getURL}/view" tal:content="python:context.lemill_tool.shortenTitle(obj.Title, 48)">PLACEHOLDER</a> 
    20             </td> 
    21         </tr> 
    22     </table> 
    23    </span>     
    24     <h1 i18n:translate="heading_browse_content">Browse content</h1> 
    25     <ul> 
    26         <li> 
    27             <a i18n:translate="label_browse_by_language" href="language" class="byTextsFont">By language</a>: 
    28             <span tal:repeat="result context/top3languages | nothing"> 
    29                 <a href="" tal:attributes="href python:'language?language=%s' % here.url_quote(result)" tal:content="python:here.script_getPrettyLanguage(result)">PLACEHOLDER</a>, 
    30             </span> 
    31             <a href="rebuildTop3s" tal:condition="context/amIManager">( rebuild top results )</a> 
    32             <a href="language">...</a> 
    33         </li> 
    34         <li> 
    35             <a i18n:translate="label_browse_by_subject_area" href="subject_area" class="byTextsFont">By subject area</a>: 
    36             <span tal:repeat="result context/top3subject_areas | nothing"> 
    37                 <a href="" tal:attributes="href python:'subject_area?subject_area=%s' % here.url_quote(result)" tal:content="result" i18n:translate="">PLACEHOLDER</a>, 
    38             </span> 
    39             <a href="subject_area">...</a> 
    40         </li> 
    41         <li> 
    42             <a i18n:translate="label_browse_by_target_group" href="target_group" class="byTextsFont">By target group</a>: 
    43             <span tal:repeat="result context/top3target_groups | nothing"> 
    44                 <a href="" tal:attributes="href python:'target_group?target_group=%s' % here.url_quote(result)" tal:content="result" i18n:translate="">PLACEHOLDER</a>, 
    45             </span> 
    46             <a href="target_group">...</a> 
    47         </li>         
    48         <li> 
    49             <a i18n:translate="label_browse_by_tags" href="tags" class="byTextsFont">By tags</a>: 
    50             <span tal:repeat="result context/top3tags | nothing"> 
    51                 <a href="" tal:attributes="href python:'tags?tag=%s' % here.url_quote(result)" tal:content="result">PLACEHOLDER</a>, 
    52             </span> 
    53             <a href="tags">...</a> 
    54         </li> 
    55     </ul> 
    56     <div style="margin-top:30px"> 
    57         <a i18n:translate="label_whats_going_on" href="recent">What's going on?</a> | <a tal:attributes="href string:${portal_url}/content/webpages/lemill-faq" i18n:translate="label_faq" href="lemill-faq">FAQ</a> 
     7<metal:main fill-slot="main">    
     8   <div class="title grid"> 
     9        <h1 i18n:translate="heading_featured_content">Featured content</h1> 
     10   </div> 
     11   <div class="clear"></div> 
     12   <span tal:define="samples here/getSamples" tal:condition="samples" tal:omit-tag="">  
     13       <tal:coverimages repeat="obj samples">    
     14         <div class="content_border featured_item grid" tal:define="first repeat/obj/start; last repeat/obj/end;" tal:attributes="style  python:test(first, 'margin-left:0', test(last, 'margin-right:0', ''));"> 
     15            &nbsp;<a href="#" title="Cover image" tal:attributes="href string:${obj/getURL}/view; title obj/Title | nothing;">              
     16              <img alt="Cover image" valign="middle" tal:attributes="src string:${obj/getURL}/coverImage; alt obj/Title | nothing;" src="images/default_learningresource.png" /> 
     17            </a>&nbsp; 
     18         </div> 
     19      </tal:coverimages> 
     20      <div class="clear"></div> 
     21 
     22      <tal:titles repeat="obj samples"> 
     23        <div class="resource_title grid" tal:define="first repeat/obj/start; last repeat/obj/end;" tal:attributes="style python:test(first, 'margin-left:0', test(last, 'margin-right:0', ''));"> 
     24            <a href="#"  tal:attributes="href string:${obj/getURL}/view" tal:content="python:context.lemill_tool.shortenTitle(obj.Title, 48)">PLACEHOLDER</a> 
     25        </div> 
     26      </tal:titles> 
     27   </span> 
     28 
     29 
     30  <div class="browse_links grid" tal:define="lang_filter context/getLanguageFilter"> 
     31    <dl> 
     32        <dt><a i18n:translate="label_languages" href="cloud?base=language">Languages</a></dt> 
     33        <dd><span tal:repeat="result context/top3languages | nothing"> 
     34            <a href="" tal:attributes="href python:'browse?language=%s' % result" tal:content="python:here.script_getPrettyLanguage(result)">PLACEHOLDER</a>, </span><a href="rebuildTop3s" tal:condition="context/amIManager">( rebuild top results )</a><a href="cloud?base=language">...</a> 
     35        </dd> 
     36 
     37        <dt><a i18n:translate="label_subject_areas" href="" tal:attributes="href string:cloud?${lang_filter}base=subject_area">Subject areas</a></dt> 
     38        <dd><span tal:repeat="result python:context.portal_catalog.getTopFive(results,'getSubject_area', 'browse?%ssubject_area=' % lang_filter)"> 
     39                <a href="" tal:attributes="href python:result[1]" tal:content="python:result[0]" i18n:translate="">PLACEHOLDER</a>, 
     40            </span><a href="" tal:attributes="href string:cloud?${lang_filter}base=subject_area">...</a> 
     41        </dd> 
     42        <dt><a i18n:translate="label_target_groups" href="" tal:attributes="href string:cloud?${lang_filter}base=target_group">Target groups</a></dt> 
     43        <dd><span tal:repeat="result python:context.portal_catalog.getTopFive(results,'getTarget_group', 'browse?%starget_group=' % lang_filter)"> 
     44                <a href="" tal:attributes="href python:result[1]" tal:content="python:result[0]" i18n:translate="">PLACEHOLDER</a>, 
     45            </span><a href="" tal:attributes="href string:cloud?${lang_filter}base=target_group">...</a> 
     46        </dd>         
     47        <dt><a i18n:translate="label_tags" href=""  tal:attributes="href string:cloud?${lang_filter}base=tags">Tags</a></dt> 
     48        <dd><span tal:repeat="result python:context.portal_catalog.getTopFive(results,'getTags', 'browse?%stags=' % lang_filter)"> 
     49                <a href="" tal:attributes="href python:result[1]" tal:content="python:result[0]">PLACEHOLDER</a>, 
     50            </span><a href="" tal:attributes="href string:cloud?${lang_filter}base=tags">...</a> 
     51        </dd> 
     52    </dl> 
    5853    </div> 
    59 </div> 
     54</metal:main> 
    6055</body> 
    6156</html> 
  • trunk/skins/lemill/lemill_grid.css

    r3046 r3052  
     1/* Basic tags */ 
     2 
    13body { 
    24    margin-left: auto; 
    35    margin-right: auto; 
    46    width: 960px; 
     7    font-family: Verdana, Geneva, Arial, Helvetica, sans-serif; 
     8    font-size: 13px; 
     9} 
     10 
     11img { 
     12    border:0; 
     13} 
     14 
     15h1 { 
     16    font-family: "Lucida Grande", Verdana, Lucida, Helvetica, Arial, sans-serif; 
     17    font-weight: normal; 
     18    margin: 0 0 0.25em 0; 
     19    border-bottom: 1px solid #8cacbb;     
     20} 
     21 
     22a { 
     23    color: #2299bb; 
     24} 
     25 
     26input[type="text"] { 
     27    font-size: 13px; 
     28} 
     29 
     30ul { 
     31    list-style-image:url("images/bullet.gif"); 
     32    list-style-type:square; 
     33    line-height:1.5; 
     34} 
     35 
     36label { 
     37    font-weight: bold; 
     38} 
     39 
     40/* Visual adjustments */ 
     41 
     42.small { 
     43    font-size:11px; 
    544} 
    645 
     
    1049    position: relative; 
    1150    margin: 4px 10px 4px 10px; 
    12     background-color: #aaffaa; 
    13     /* border: 1px solid black;*/ 
    14     min-height: 25px; 
    15     text-align: center; 
    16     vertical-align: middle; 
    17 } 
    18  
    19  
    20 /* Clear Floated Elements 
    21 ----------------------------------------------------------------------------------------------------*/ 
    22  
    23 /* http://sonspring.com/journal/clearing-floats */ 
     51} 
    2452 
    2553.clear { 
     
    3260} 
    3361 
     62.discreet { 
     63    font-size:11px; 
     64    color:#76797c; 
     65} 
    3466/* http://perishablepress.com/press/2008/02/05/lessons-learned-concerning-the-clearfix-css-hack */ 
    3567 
     
    6496    margin-right: 0; 
    6597} 
    66  
     98.no_padding { 
     99    padding-left: 0 !important; 
     100} 
     101 
     102/* Grid elements and related adjustments */ 
    67103 
    68104div.languages { 
     
    73109    width:220px; 
    74110    height:25px; 
     111    text-align:right; 
     112} 
     113div.read_only_mode { 
     114    background-color:#FEF49C;  
     115    padding:0.5em; 
     116    width:700px;     
    75117} 
    76118div.logo { 
    77119    width:220px; 
    78     height:110px; 
     120    height:100px; 
     121    text-align:center; 
     122    border-radius: 5px; 
     123    -moz-border-radius: 5px; 
    79124} 
    80125div.top_area { 
    81126    width:700px; 
    82     background-color: #ffdddd; 
    83127} 
    84128div.search { 
    85129    width:700px; 
    86     height:60px;     
     130    height:38px;     
    87131    margin-left: 0; 
    88132    margin-right: 0; 
    89 } 
     133    text-align:right; 
     134    padding-top: 11px; 
     135} 
     136 
     137input#searchGadget, input#search_textfield { 
     138    width:240px; 
     139    height:22px; 
     140    border:1px solid #bbbbbb; 
     141} 
     142input#searchbutton { 
     143    width:96px; 
     144} 
     145 
     146div.toplink { 
     147    text-align: center; 
     148    border-radius: 5px; 
     149    -moz-border-radius: 5px; 
     150    background-color: #BBBBBB; 
     151    width:160px; 
     152} 
     153.toplink a { 
     154    padding-top: 10px; 
     155    padding-bottom: 10px; 
     156    color:white; 
     157    font-family: "Trebuchet MS", Geneva, Arial, Helvetica, sans-serif;    
     158    font-size: 16px; 
     159    text-decoration: none; 
     160    display:block; 
     161} 
     162     
    90163 
    91164div.content_toplink { 
    92     width:160px; 
    93     height:40px; 
    94     margin-left: 0;     
    95 } 
    96 div.methods_toplink { 
    97     width:160px; 
    98     height:40px; 
    99 } 
    100 div.tools_toplink { 
    101     width:160px; 
    102     height:40px; 
     165    margin-left: 0; 
     166} 
     167.content_selected, .content_toplink:hover { 
     168    background-color:#77BB22 !important; 
     169} 
     170.methods_selected, .methods_toplink:hover { 
     171    background-color:#FF7700 !important; 
     172} 
     173.tools_selected, .tools_toplink:hover { 
     174    background-color:#666699 !important; 
    103175} 
    104176div.community_toplink { 
    105     width:160px; 
    106     height:40px; 
    107177    margin-right: 0;     
     178} 
     179.community_selected, .community_toplink:hover { 
     180    background-color:#77AABB !important; 
    108181} 
    109182div.portlets { 
    110183    width:220px; 
    111     background-color: #ffdddd; 
    112 } 
    113 div.portlet { 
    114     width:220px; 
    115     margin-left: 0; 
    116     margin-right: 0; 
    117184} 
    118185div.main { 
    119186    width:700px; 
    120     background-color: #ffdddd; 
     187    line-height: 1.5;  
    121188}     
    122189div.title { 
     
    126193    margin-right: 0; 
    127194} 
    128 div.feat_content_coverimage { 
    129     width:160px; 
    130     height:160px; 
    131 }     
    132 div.feat_method_coverimage { 
    133     width:160px; 
    134     height:160px; 
    135 }     
    136 div.feat_tool_coverimage { 
    137     width:160px; 
    138     height:160px; 
    139 }     
    140 div.feat_community_coverimage { 
    141     width:160px; 
    142     height:160px; 
    143 }     
     195div.featured_item { 
     196    width:158px; 
     197    height:158px; 
     198    text-align:center; 
     199    line-height:158px; 
     200    vertical-align:middle; 
     201} 
     202div.content_border { 
     203    border:1px solid #77BB22; 
     204} 
     205div.methods_border { 
     206    border:1px solid #FF7700; 
     207} 
     208div.tools_border { 
     209    border:1px solid #666699; 
     210} 
     211div.community_border { 
     212    border:1px solid #77AABB; 
     213} 
     214.featured_item img { 
     215    max-height:120px; 
     216    max-width:120px; 
     217} 
     218     
    144219div.resource_title { 
    145220    width:160px; 
    146     height:32px; 
     221    height:48px; 
     222    text-align:center; 
     223    line-height: 1; 
    147224}     
    148225div.lemill_numbers { 
     
    151228    margin-left: 0; 
    152229    margin-right: 0; 
     230    text-align:center; 
     231    padding-top:20px; 
     232    padding-bottom:20px; 
     233    background-color: #dddddd; 
     234    border-radius: 5px;  
     235    -moz-border-radius: 5px; 
    153236} 
    154237div.blog_header { 
    155238    width:700px; 
    156239    height:30px; 
     240    padding-top:8px; 
    157241    margin-left: 0; 
    158242    margin-right: 0; 
     
    161245    width:940px; 
    162246    height:60px; 
     247    text-align:center; 
     248    padding-top:20px; 
     249    padding-bottom:20px; 
     250    background-color: #dddddd; 
     251    border-radius: 5px; 
     252    -moz-border-radius: 5px; 
    163253} 
    164254div.sponsor_logos { 
    165255    width:940px; 
    166256    height:100px; 
    167 } 
    168 div.browse_content { 
    169     width:700px; 
    170     height:235px; 
    171     margin-left: 0; 
    172     margin-right: 0; 
     257    text-align:center; 
     258    vertical-align:middle; 
    173259} 
    174260div.dashboard_widget { 
     
    180266    height:320px;     
    181267} 
     268 
     269/* Section front pages */ 
     270 
     271div.browse_links { 
     272    width:700px; 
     273    margin-left: 0; 
     274    margin-right: 0; 
     275} 
     276.browse_links dl { 
     277    margin-left: 0; 
     278    margin-top: 0; 
     279} 
     280.browse_links dt { 
     281    font: bold 14pt Trebuchet MS; 
     282    padding-top: 1em; 
     283} 
     284.browse_links dd { 
     285    margin-left: 0; 
     286} 
     287 
     288 
     289/* Folded things */ 
     290.folding_trigger .folded { 
     291    background: white url('images/folded_in.png') no-repeat left top; 
     292    padding-left: 1.5em; 
     293    } 
     294.folding_trigger .unfolded { 
     295    background: white url('images/folded_out.png') no-repeat left top; 
     296    padding-left: 1.5em; 
     297    } 
     298 
     299.folding_area { 
     300    background-color: #dddddd; 
     301    padding: 1em; 
     302    border-radius: 5px; 
     303    -moz-border-radius: 5px; 
     304} 
     305 
     306/* Search results */ 
     307 
     308ul.result_list { 
     309    list-style-type:none; 
     310    list-style-image:none; 
     311    padding-left:0; 
     312} 
     313ul.result_list li { 
     314    clear:both; 
     315    padding-top:1em; 
     316    padding-bottom:1em; 
     317} 
     318div.list_cover_box { 
     319    float:left;  
     320    width:150px; 
     321    height:150px; 
     322    line-height: 150px; 
     323    border: 1px solid #bbbbbb; 
     324    text-align: center; 
     325    vertical-align: middle; 
     326} 
     327div.list_cover_box img { 
     328    max-height:120px; 
     329    max-width:120px; 
     330}  
     331 
     332div.list_data_box { 
     333    float:left; 
     334    padding-left: 2em; 
     335    width:500px; 
     336}          
     337 
     338div.listingBar { 
     339    width:700px; 
     340    clear:both; 
     341    margin: 1em 0; 
     342    text-align:center; 
     343    background-color: #dddddd; 
     344    border-radius: 5px; 
     345    -moz-border-radius: 5px; 
     346    height:24px; 
     347} 
     348 
     349div.listingBar span.next { 
     350    text-align: right; 
     351    float:right; 
     352    margin-left: 1em; 
     353} 
     354div.listingBar span.previous { 
     355    text-align: left; 
     356    float:left; 
     357    margin-right: 1em; 
     358} 
     359 
     360/* Clouds */ 
     361div.cloud a { 
     362    /*color:#76797c;*/ 
     363    text-decoration: none; 
     364    font-family: Trebuchet MS; 
     365} 
     366div.cloud a:hover { 
     367    text-decoration: underline; 
     368} 
     369.size1 {font-size:10pt;} 
     370.size2 {font-size:12pt;} 
     371.size3 {font-size:16pt;} 
     372.size4 {font-size:20pt;} 
     373.size5 {font-size:24pt;} 
     374.size6 {font-size:28pt;} 
     375.size7 {font-size:34pt;} 
     376.size8 {font-size:40pt;} 
     377 
     378/* Portlets */ 
     379 
     380div.portlet { 
     381    margin-left: 0; 
     382    margin-right: 0; 
     383    border-width:1px; 
     384    border-style: solid;  
     385    width: 218px;    
     386} 
     387 
     388.portlet ul { 
     389    padding-left: 1.8em; 
     390    padding-top: 0.4em; 
     391    padding-bottom: 0.4em; 
     392    margin: 0; 
     393    line-height: 1.8; 
     394} 
     395 
     396div.tagline { 
     397    height:125px; 
     398    line-height: 1.5;  
     399    background-color:#77BB22; 
     400    width:200px; 
     401    margin-top:0; 
     402    margin-bottom:0; 
     403    padding:10px; 
     404    color:white; 
     405    font-family: "Trebuchet MS", Geneva, Arial, Helvetica, sans-serif;    
     406    font-size: 16px; 
     407    text-decoration: none; 
     408    -moz-border-radius-topleft: 5px; 
     409    -moz-border-radius-topright: 5px; 
     410    border-top-right-radius: 5px; 
     411    border-top-left-radius: 5px; 
     412 
     413} 
     414div.loginportlet { 
     415    font-family: "Trebuchet MS", Geneva, Arial, Helvetica, sans-serif;    
     416    font-size: 16px; 
     417    line-height: 1.5;  
     418    height:225px; 
     419    background-color:#77BB22; 
     420    padding:10px; 
     421    width:200px; 
     422    color:white; 
     423    margin-top:0; 
     424    margin-bottom:0; 
     425    border-bottom-right-radius: 5px; 
     426    border-bottom-left-radius: 5px; 
     427    -moz-border-radius-bottomleft: 5px; 
     428    -moz-border-radius-bottomright: 5px; 
     429} 
     430.loginportlet input[type="text"], .loginportlet input[type="password"] { 
     431    width:170px; 
     432    margin-top: 4px; 
     433    margin-bottom: 4px; 
     434} 
     435.loginportlet input[type='submit'] { 
     436    font-family: "Trebuchet MS", Geneva, Arial, Helvetica, sans-serif;    
     437    font-size: 16px; 
     438    width:100px; 
     439    background-color:#77BB22; 
     440    color: white; 
     441    margin-top: 4px; 
     442    border: 2px solid white; 
     443    border-right-color: #ddffdd;  
     444    border-bottom-color: #eaffea;  
     445    border-radius: 5px; 
     446    -moz-border-radius: 5px; 
     447} 
     448 
     449.loginportlet label, .loginportlet .small { 
     450    font-family: Verdana, Geneva, Arial, Helvetica, sans-serif; 
     451    font-size:11px; 
     452    font-weight:normal; 
     453} 
     454 
     455.loginportlet a,.loginportlet a:visited { 
     456    color:white; 
     457} 
     458 
     459.portlet-title { 
     460    color: #ffffff; 
     461    font-weight: bold; 
     462    height: 24px; 
     463    line-height: 21px; 
     464    padding-left: 12px; 
     465    width:204; 
     466} 
     467.portlet-title a { 
     468    color: #ffffff; 
     469    font-weight: bold; 
     470    text-decoration: none; 
     471} 
     472.smallicon { 
     473    display: inline; 
     474    width: 24px; 
     475    height: 24px; 
     476    vertical-align: middle; 
     477} 
     478 
     479 
     480div.browse_options { 
     481    width: 218px; 
     482} 
     483.browse_options form { 
     484    padding: 0px 10px 10px 10px; 
     485    line-height: 1.5;  
     486} 
     487 
     488.browse_options select { 
     489    width:160px; 
     490} 
     491 
     492 
     493/* LiveSearch styles */ 
     494 
     495 
     496.LSResult { 
     497    position: relative; 
     498    display: block; 
     499    padding-top: 5px; 
     500    margin: 0; 
     501    z-index: 3; 
     502} 
     503 
     504 
     505.livesearchContainer { 
     506    background-color: white; 
     507    margin-top: 0; 
     508    position: absolute; 
     509    top: 0; 
     510    right: 20px; 
     511    text-align: left; 
     512    border: 1px solid #bbbbbb; 
     513    width: 320px; 
     514    text-transform: none; 
     515    font-size: 11px; 
     516} 
     517 
     518.livesearchContainer ul { 
     519    list-style-image: none; 
     520    list-style-type: none; 
     521    margin-left: 0.5em; 
     522    padding-left: 0; 
     523    line-height: 1.4; 
     524}     
     525 
     526.livesearchContainer a { 
     527    text-decoration: none; 
     528    color: black; 
     529} 
     530 
     531.livesearchContainer li.selectable:hover, .LSHighlight { 
     532    background-color: #cccccc; 
     533} 
     534 
     535/* Workaround for Internet Explorer's broken z-index implementation */ 
     536.LSIEFix { 
     537    background-color: transparent; 
     538    padding: 0.5em !important; 
     539    z-index: 20; 
     540} 
     541 
  • trunk/skins/lemill/lemill_portfolio_view.pt

    r3045 r3052  
    88             tal:define="dummy python:request.set('disable_border',1)" /> 
    99 
    10 <metal:block fill-slot="column_one_slot"> 
     10<metal:block fill-slot="portlet_slot"> 
    1111<td id="tb-portal-column-one" width="210" valign="top" tal:define="here here/getMemberFolder | here/getBlog | nocall:context; portlet_path here/getPortletPath|nothing"> 
    1212            <tal:hasportlet condition="portlet_path"><metal:portletmacro metal:use-macro="python:path(portlet_path)" /></tal:hasportlet>             
  • trunk/skins/lemill/lemill_tools_view.pt

    r3000 r3052  
    55<body> 
    66 
    7 <div metal:fill-slot="main" style="width:100%"> 
    8    <span tal:define="samples context/getSamples" tal:condition="samples" tal:omit-tag="">    
    9     <h1 i18n:translate="heading_featured_tools">Featured tools</h1>     
    10     <div metal:use-macro="here/lemill_activities_view/macros/featured"/> 
    11    </span>     
    12     <h1 i18n:translate="heading_browse_tools">Browse tools</h1>     
    13     <ul> 
    14         <li> 
    15             <a i18n:translate="label_browse_by_language" href="language" class="byTextsFont">By language</a>: 
    16             <span tal:repeat="result context/top3languages"> 
    17                 <a href="" tal:attributes="href python:'language?language='+here.url_quote(result)" tal:content="python:here.script_getPrettyLanguage(result)">PLACEHOLDER</a>, 
    18             </span> 
    19             <a href="language">...</a> 
    20         </li>         
    21         <li> 
    22             <a i18n:translate="label_browse_by_title_cloud" href="browse_tools" class="byTextsFont">By title cloud</a> 
    23         </li>             
    24         <li> 
    25             <a i18n:translate="label_browse_by_tags" href="tags" class="byTextsFont">By tags</a>: 
    26             <span tal:repeat="result context/top3tags"> 
    27                 <a href="" tal:attributes="href python:'tags?tag='+here.url_quote(result)" tal:content="result">PLACEHOLDER</a>, 
    28             </span> 
    29             <a href="tags">...</a> 
    30         </li> 
    31     </ul>     
    32 </div> 
     7<metal:main fill-slot="main"> 
     8    <div class="title grid"> 
     9        <h1 i18n:translate="heading_featured_tools">Featured tools</h1> 
     10    </div> 
     11    <div class="clear"></div> 
     12   <span tal:define="samples here/getSamples" tal:condition="samples" tal:omit-tag="">  
     13       <tal:coverimages repeat="obj samples">    
     14         <div class="tools_border featured_item grid" tal:define="first repeat/obj/start; last repeat/obj/end;" tal:attributes="style  python:test(first, 'margin-left:0', test(last, 'margin-right:0', ''));"> 
     15            &nbsp;<a href="#" title="Cover image" tal:attributes="href obj/getURL; title obj/Title | nothing;">              
     16              <img alt="Cover image" valign="middle" tal:attributes="src string:${obj/getURL}/coverImage; alt obj/Title | nothing;" src="images/default_learningresource.png" /> 
     17            </a>&nbsp; 
     18         </div> 
     19      </tal:coverimages> 
     20      <div class="clear"></div> 
     21 
     22      <tal:titles repeat="obj samples"> 
     23        <div class="resource_title grid" tal:define="first repeat/obj/start; last repeat/obj/end;" tal:attributes="style python:test(first, 'margin-left:0', test(last, 'margin-right:0', ''));"> 
     24            <a href="#"  tal:attributes="href obj/getURL" tal:content="python:context.lemill_tool.shortenTitle(obj.Title, 48)">PLACEHOLDER</a> 
     25        </div> 
     26      </tal:titles> 
     27   </span> 
     28 
     29 
     30  <div class="browse_links grid" tal:define="lang_filter context/getLanguageFilter"> 
     31    <dl> 
     32        <dt><a i18n:translate="label_languages" href="cloud?base=language">Languages</a></dt> 
     33        <dd><span tal:repeat="result context/top3languages | nothing"> 
     34            <a href="" tal:attributes="href python:'language?language=%s' % here.url_quote(result)" tal:content="python:here.script_getPrettyLanguage(result)">PLACEHOLDER</a>, </span><a href="rebuildTop3s" tal:condition="context/amIManager">( rebuild top results )</a><a href="cloud?base=language">...</a> 
     35        </dd> 
     36        <dt><a i18n:translate="label_popularity" href="" tal:attributes="href string:cloud?${lang_filter}base=title">Popularity</a></dt> 
     37        <dd></dd> 
     38 
     39        <dt><a i18n:translate="label_tags" href=""  tal:attributes="href string:cloud?${lang_filter}base=tags">Tags</a></dt> 
     40        <dd><span tal:repeat="result python:context.portal_catalog.getTopFive(results,'getTags','browse?%stags=' % lang_filter)"> 
     41                <a href="" tal:attributes="href python:result[1]" tal:content="python:result[0]">PLACEHOLDER</a>, 
     42            </span><a href="" tal:attributes="href string:cloud?${lang_filter}base=tags">...</a> 
     43        </dd> 
     44    </dl> 
     45    </div> 
     46</metal:main> 
    3347</body> 
    3448</html> 
    3549 
     50 
  • trunk/skins/lemill/livesearch_reply.py

    r2887 r3052  
    55##bind script=script 
    66##bind subpath=traverse_subpath 
    7 ##parameters=q,limit=10 
     7##parameters=q 
    88##title=Determine whether to show an id in an edit form 
    99 
     
    1212from Products.PythonScripts.standard import url_quote 
    1313 
    14 prettify = context.lemill_tool.pretty_title_or_id 
     14lt = getToolByName(context, 'lemill_tool') 
     15pc = getToolByName(context, 'portal_catalog') 
     16prettify = lt.pretty_title_or_id 
    1517 
    16 MAX_TITLE = 29 
    1718 
    18 catalog = context.portal_catalog 
     19def make_link(result): 
     20    full_title=unicode(result[0], 'utf-8', 'ignore') 
     21    if len(full_title) >= MAX_TITLE: 
     22        dots='...' 
     23    else: 
     24        dots='' 
     25    type_name= ts.translate(lt.getTypeName(result[2]), domain='lemill')  
     26    return u'''<a href="%s" title="%s">%s%s</a> <span class="discreet">(%s)</span>''' % (result[1], full_title, full_title[:MAX_TITLE],dots, type_name) 
    1927 
    20 def quotestring(s): 
    21     return '"%s"' % s 
    22  
    23 def quote_bad_chars(s): 
    24     bad_chars = ["(", ")"] 
    25     for char in bad_chars: 
    26         s = s.replace(char, quotestring(char)) 
    27     return s 
     28limit = 7 
     29MAX_TITLE = 35 
    2830 
    2931# for now we just do a full search to prove a point, this is not the 
     
    3941# not interpret them as metachars 
    4042##q = re.compile(r'[\*\?\-\+]+').sub(' ', q) 
     43 
    4144for char in '?-+*': 
    4245    q = q.replace(char, ' ') 
     
    4649else: 
    4750    r = " AND ".join(r) 
    48 r = quote_bad_chars(r)+'*' 
    4951searchterms = url_quote(r.replace(' ','+')) 
    5052 
    51 try: 
    52     results = catalog(SearchableText=r, portal_type=context.lemill_tool.getSearchableTypes(), getState=('public', 'draft')) 
    53 except: 
    54     results = [] 
     53results1 = pc.titleSearch(title=r, sort_limit=limit) 
     54results1 = pc.fastLinks(results1, limit) 
     55# Full text results shouldn't contain doubles from first result set 
     56limit2=max((limit, len(results1)*2)) 
     57pre_results2= pc.fulltextSearch(SearchableText=r, sort_limit=limit2) 
     58pre_results2 = pc.fastLinks(pre_results2, limit2) 
     59titles=[r[0] for r in results1] 
     60results2=[r for r in pre_results2 if r[0] not in titles][:limit] 
    5561 
    5662RESPONSE = context.REQUEST.RESPONSE 
     
    6066#   &darr;      --> &#8595; 
    6167#   &hellip;    --> &#8230; 
    62 legend_livesearch = _('legend_livesearch', default='LiveSearch &#8595;') 
    63 label_no_results_found = _('label_no_results_found', default='No matching results found.') 
    64 label_advanced_search = _('label_advanced_search', default='Advanced Search&#8230;') 
    6568label_show_all = _('label_show_all', default='Show all&#8230;') 
    66  
     69label_no_results = _('label_no_results_found', default='No results found') 
    6770ts = getToolByName(context, 'translation_service') 
    6871 
    69 if not results: 
    70     print '''<fieldset class="livesearchContainer">''' 
    71     print '''<legend id="livesearchLegend">%s</legend>''' % ts.translate(legend_livesearch,domain='plone') 
     72if not (results1 or results2): 
     73    print '''<div class="livesearchContainer">''' 
    7274    print '''<div class="LSIEFix">''' 
    73     print '''<div id="LSNothingFound">%s</div>''' % ts.translate(label_no_results_found,domain='plone') 
    74     print '''<div class="LSRow">''' 
    75     print '<a href="lemill_search_form" style="font-weight:normal">%s</a>' % ts.translate(label_advanced_search,domain='plone') 
     75    print ts.translate(label_no_results) 
    7676    print '''</div>''' 
    7777    print '''</div>''' 
    78     print '''</fieldset>''' 
    7978 
    8079else: 
    81     print '''<fieldset class="livesearchContainer">''' 
    82     print '''<legend id="livesearchLegend">%s</legend>''' % ts.translate(legend_livesearch,domain='plone') 
     80    print '''<div class="livesearchContainer">''' 
    8381    print '''<div class="LSIEFix">''' 
    84     print '''<ul class="LSTable">''' 
    85     for result in results[:limit]: 
    86         print '''<li class="LSRow">''', 
    87         full_title = prettify(result) 
    88         if not isinstance(full_title, unicode): 
    89             full_title = unicode(full_title, 'utf-8', 'ignore') 
    90         if len(full_title) >= MAX_TITLE: 
    91             display_title = u''.join((full_title[:MAX_TITLE],u'...')) 
    92         else: 
    93             display_title = full_title 
     82    print '''<ul>''' 
     83    #print '''<li class="LSLabel"><b> Titles:</b> </li>''' 
     84    for result in results1: 
     85        print '''<li class="selectable">''', 
     86        print make_link(result) 
     87        print '''</li>''' 
     88    print '''<hr/>''' 
     89    #print '''<li class="LSLabel" style="margin-top:4px;">Text and tags:</li>''' 
     90    for result in results2: 
     91        print '''<li class="selectable">''', 
     92        print make_link(result) 
     93        print '''</li>''' 
    9494 
    95         print u'''<a href="%s/view" title="%s">%s</a>''' % (result.getURL(), full_title, display_title) 
    96         print '''<span class="discreet">[%s%%]</span>''' % result.data_record_normalized_score_ 
    97         print '''</li>''' 
    98         full_title, display_title = None, None 
    99  
    100     print '''<li class="LSRow">''' 
    101     print '<a href="lemill_search_form" style="font-weight:normal">%s</a>' % ts.translate(label_advanced_search) 
    102     print '''</li>''' 
    103  
    104     if len(results)>limit: 
     95    if len(results2)==limit: 
    10596        # add a more... row 
    106         print '''<li class="LSRow">''' 
    107         print '<a href="%s" style="font-weight:normal">%s</a>' % ('lemill_search_results?SearchableText=' + searchterms, ts.translate(label_show_all)) 
    108         print '''</li>''' 
     97        print '''<hr/>''' 
     98        print '''<li class="selectable" style="margin-top:4px;"><a href="search?q=%s">%s</a></li>''' % (searchterms, ts.translate(label_show_all)) 
    10999    print '''</ul>''' 
    110100    print '''</div>''' 
    111     print '''</fieldset>''' 
     101    print '''</div>''' 
    112102 
    113103return printed 
  • trunk/skins/lemill/login_form.cpt

    r2410 r3052  
    88    <metal:block fill-slot="top_slot" 
    99                 tal:define="dummy python:request.set('disable_border',1)" /> 
    10     <metal:block fill-slot="column_one_slot" /> 
     10    <metal:block fill-slot="portlet_slot" /> 
    1111    <metal:block fill-slot="column_two_slot" /> 
    1212</head> 
  • trunk/skins/lemill/main_template.pt

    r3045 r3052  
    1313</div> 
    1414<div class="login grid" tal:condition="not:site_properties/readonly_mode"> 
    15     <ul tal:condition="not:isAnon" id="tb-portal-personaltools">     
    16         <li class="portalUser">  
    17             <a class="visualCaseSensitive" 
    18                 tal:content="memberid" 
    19                 tal:attributes="href memberfolder/absolute_url | portal/community/my_page" 
    20                 href="my_page"> 
    21                     PLACEHOLDER 
    22             </a> 
    23         </li> 
    24         <li><a tal:attributes="href string:${portal_url}/logout" i18n:translate="">Log out</a></li> 
    25     </ul><ul tal:condition="isAnon" id="tb-portal-personaltools">     
    26         <li><a tal:attributes="href string:${portal_url}/login_form" i18n:translate="">Log in</a></li> 
    27         <li><a href="" tal:attributes="href string:${portal_url}/join_form" i18n:translate="">Join</a></li> 
    28     </ul> 
     15    <a tal:content="memberid" tal:attributes="href memberfolder/absolute_url | portal/community/my_page" tal:condition="not:isAnon" href="my_page">my page</a> 
     16    <a tal:attributes="href string:${portal_url}/login_form" i18n:translate="" tal:condition="isAnon">Log in</a> 
     17    &nbsp;&nbsp;&nbsp; 
     18    <a tal:attributes="href string:${portal_url}/logout" i18n:translate="" tal:condition="not:isAnon">Log out</a> 
     19    <a href="" tal:attributes="href string:${portal_url}/join_form" i18n:translate="" tal:condition="isAnon">Join</a> 
    2920</div> 
    30 <div class="read_only_mode grid" tal:condition="site_properties/readonly_mode" style="background-color:#FEF49C; padding:0.5em"> 
     21 
     22<div class="read_only_mode grid" tal:condition="site_properties/readonly_mode"> 
    3123    <b i18n:translate="readonly_mode_notification">We are updating LeMill and the service is in read-only mode. You can browse LeMill, but not log in or edit content. The service will be back in few hours. Apologies for the inconvenience.</b>  
    3224</div></metal:toolbar> 
    33 <table id="tb-portal-header" summary="Header" width="760" border="0" align="center" cellpadding="0" cellspacing="0"> 
    34     <tr tal:define="section_name here/getSectionFromURL; georgian python:here.portal_languages.getLanguageCookie()=='ka'"> 
    35         <td width="200" class="logo" tal:attributes="width python:test(georgian, 160, 200)"><a href="/" tal:attributes="href portal_url" tal:define="portal_title portal_properties/title;"><img tal:attributes="src string:${portal_url}/images/logo_${section_name}.png; width python:test(georgian, 160, 200)" alt="" /></a></td> 
    36         <td width="420" tal:attributes="width python:test(georgian, 500, 420)"> 
    37             <ul id="tb-portal-globalnav"> 
    38                 <li id="portaltab-content"> 
    39                     <a href="" i18n:translate="" tal:attributes="href string:${portal_url}/content; class python:test(section_name=='content', 'selected','plain')">Content</a> 
    40                 </li> 
    41                 <li id="portaltab-methods"> 
    42                     <a href="" i18n:translate="" tal:attributes="href string:${portal_url}/methods; class python:test(section_name=='methods', 'selected','plain')">Methods</a> 
    43                 </li> 
    44                 <li id="portaltab-tools"> 
    45                     <a href="" i18n:translate="" tal:attributes="href string:${portal_url}/tools; class python:test(section_name=='tools', 'selected','plain')">Tools</a> 
    46                 </li> 
    47                 <li id="portaltab-community"> 
    48                     <a href="" i18n:translate="" tal:attributes="href string:${portal_url}/community; class python:test(section_name=='community', 'selected','plain')">Community</a> 
    49                 </li> 
    50             </ul> 
    51         </td> 
    52         <td width="140" align="right" valign="middle" tal:attributes="width python:test(georgian, 100, 140)">         
    53                      <div metal:use-macro="here/global_searchbox/macros/quick_search"> 
    54                The quicksearch box, normally placed at the top right 
    55              </div> 
    56         </td> 
    57     </tr> 
    58 </table></metal:topslot> 
    59 <metal:columns define-slot="columns"><table id="tb-portal-columns" summary="Main content" width="760"  border="0" align="center" cellpadding="0" cellspacing="0"> 
    60     <tr> 
    61         <td id="tb-portal-column-one" metal:define-slot="column_one_slot" width="210" valign="top" tal:define="portlet_path here/getPortletPath|nothing"> 
    62             <tal:hasportlet condition="portlet_path"><metal:portletmacro metal:use-macro="python:path(portlet_path)" /></tal:hasportlet> 
    63         </td> 
    64         <td id="tb-portal-column-content" tal:define="tabindex python:Iterator(pos=0)" width="550" valign="top"> 
    65                     <div metal:use-macro="here/global_statusmessage/macros/portal_message"/> 
    66                     <metal:bodytext metal:define-slot="main" tal:content="nothing" /> 
    67         </td> 
    68     </tr> 
    69 </table></metal:columns> 
    70 <metal:footer define-slot="footerslot"><metal:block use-macro="here/footer/macros/portal_footer" /></metal:footer> 
     25 
     26<div class="clear"></div> 
     27<tal:shared_header tal:define="section_name here/getSectionFromURL;"> 
     28<div class="logo grid"><a href="/" tal:attributes="href portal_url" tal:define="portal_title portal_properties/title;"><img tal:attributes="src python:'%s/images/logo_%s.png' % (portal_url, section_name or 'content')" alt="" /></a></div> 
     29<div class="top_area grid"> 
     30    <div class="search grid"> 
     31        <form name="searchform" action="search" tal:attributes="action string:${portal_url}/search" style="white-space:nowrap"> 
     32           <input id="searchGadget" tabindex="" name="q" type="text" size="7" value="" title="Search Site" accesskey="4" i18n:attributes="title title_search_site;" tal:attributes="value request/q|nothing; tabindex tabindex/next;" class="searchinput" /> 
     33           <input type="submit" id="searchbutton" value="Search" i18n:attributes="value search;" /><br /> 
     34            <div class="LSResult" id="LSResult"></div> 
     35        </form> 
     36    </div> 
     37     <div class="clear"></div> 
     38    <div class="toplink content_toplink grid" tal:attributes="class python:test(section_name=='content' or not section_name, 'content_selected toplink content_toplink grid','toplink content_toplink grid')" > 
     39        <a href="" i18n:translate="" tal:attributes="href string:${portal_url}/content;" >Content</a> 
     40    </div> 
     41    <div class="toplink methods_toplink grid" tal:attributes="class python:test(section_name=='methods' or not section_name, 'methods_selected toplink methods_toplink grid','toplink methods_toplink grid')" > 
     42        <a href="" tal:attributes="href string:${portal_url}/methods;" i18n:translate="">Methods</a> 
     43    </div> 
     44    <div class="toplink tools_toplink grid" tal:attributes="class python:test(section_name=='tools' or not section_name, 'tools_selected toplink tools_toplink grid','toplink tools_toplink grid')" > 
     45        <a href="" tal:attributes="href string:${portal_url}/tools;" i18n:translate="">Tools</a> 
     46    </div> 
     47    <div class="toplink community_toplink grid" tal:attributes="class python:test(section_name=='community' or not section_name, 'community_selected toplink community_toplink grid','toplink community_toplink grid')" > 
     48        <a href="" tal:attributes="href string:${portal_url}/community;" i18n:translate="">Community</a> 
     49    </div> 
     50</div> 
     51<div class="clear"></div> 
     52</tal:shared_header> 
     53 
     54</metal:topslot> 
     55<div class="portlets grid"> 
     56    <metal:portletslot define-slot="portlet_slot"> 
     57 
     58    <metal:get_portlets tal:define="portlet_path here/getPortletPath|nothing" tal:condition="portlet_path"> 
     59        <metal:portletmacro metal:use-macro="python:path(portlet_path)" /> 
     60    </metal:get_portlets> 
     61    </metal:portletslot> 
     62</div>     
     63<div class="main grid"> 
     64    <div metal:use-macro="here/global_statusmessage/macros/portal_message"/> 
     65    <metal:bodytext metal:define-slot="main" tal:content="nothing" /> 
     66</div> 
     67<div class="clear" height="24px"></div>  
     68<div class="footer grid"> 
     69    <metal:footer define-slot="footerslot"><metal:block use-macro="here/footer/macros/portal_footer" /></metal:footer> 
     70</div> 
     71<metal:extra define-slot="extraslot"></metal:extra> 
    7172</body> 
    7273</html> 
  • trunk/skins/lemill/master.css

    r3045 r3052  
    478478} 
    479479 
    480 /* LiveSearch styles */ 
    481  
    482 .LSRes { 
    483     visibility: visible; 
    484     color: black; 
    485     background-color: white; 
    486     vertical-align: middle; 
    487     display:block; 
    488     list-style-image: none; 
    489     list-style-type: none; 
    490     text-align: left; 
    491     min-width: 16.5em; 
    492     text-transform: none; 
    493     margin-left: 0; 
    494     line-height: 1.1em; 
    495 } 
    496  
    497 #LSHighlight { 
    498     background-color: #dee7ec; 
    499     border: 1px solid #8cacbb; 
    500     color: black; 
    501 } 
    502  
    503 .LSRow { 
    504     border: 1px solid white; 
    505     white-space: normal; 
    506     padding:0; 
    507     margin: 0; 
    508     list-style-image: none; 
    509     list-style-type: none; 
    510 } 
    511  
    512 .LSRow a { 
    513     text-decoration: none; 
    514     font-weight:bold; 
    515     white-space:nowrap 
    516 } 
    517  
    518 .LSDescr { 
    519     color: #76797c; 
    520     text-transform: none; 
    521     padding-left:2.1em; 
    522     margin-top:-0.1em; 
    523 } 
    524  
    525 .LSResult { 
    526     position: relative; 
    527     display: block; 
    528     text-align: right; 
    529     padding-top: 5px; 
    530     margin: 0; 
    531     left: 3px; 
    532     z-index: 3; 
    533 } 
    534  
    535 .LSShadow { 
    536     position: relative; 
    537     text-align: right; 
    538 } 
    539  
    540 .livesearchContainer { 
    541     background-color: white; 
    542     margin-top: 0; 
    543     padding: 0 !important; 
    544     position: absolute; 
    545     right: 0px; 
    546     /* Currently exposes a rendering bug in Mozilla */ 
    547     top: 0; 
    548     white-space: normal; 
    549     visibility: visible; 
    550     text-align: left; 
    551     color: black; 
    552     border: 1px solid #8cacbb; 
    553     width: 30em; 
    554     text-transform: none; 
    555 } 
    556  
    557 * html .livesearchContainer { 
    558     padding: 1px !important; 
    559     padding-top: 0 !important; 
    560     background-color: #8cacbb; 
    561     border: 0; 
    562 } 
    563  
    564 #livesearchLegend { 
    565     line-height: 1em; 
    566     margin-top: -2em; 
    567     margin-left: -0.1em; 
    568     border: 1px solid #8cacbb; 
    569     border-bottom: 0; 
    570 } 
    571  
    572 * html #livesearchLegend { 
    573     margin-top: -1.9em; 
    574     margin-left: -8px; 
    575     position: relative; 
    576 } 
    577  
    578 /* Workaround for Internet Explorer's broken z-index implementation */ 
    579 .LSIEFix { 
    580     background-color: transparent; 
    581     padding: 0.5em !important; 
    582     z-index: 20; 
    583 } 
    584  
    585 .LSBox { 
    586     clear: left; 
    587     float: left; 
    588     text-align: right; 
    589     padding-right: 1px; 
    590     display:block; 
    591 } 
    592  
    593 #LSNothingFound { 
    594     text-align: center; 
    595     padding: 2px; 
    596 } 
    597480 
    598481 
  • trunk/skins/lemill/master.js

    r3045 r3052  
    5454    $('.requiredfield').each(function() {watchRequiredField(this);}); 
    5555 
     56 
     57/* 4. Focus on focus-wanting field or if no such field, search field  
     58*/ 
     59    $need=$('input.needs_focus:first'); 
     60    if ($need.length) { 
     61        $need.focus(); 
     62    } else { 
     63        sbox=$('input#searchGadget') 
     64        if (sbox.val()=='') { 
     65            sbox.focus(); 
     66        } 
     67    } 
    5668}); 
     69 
     70/* *** END INITIALIZATIONS *** */ 
    5771 
    5872/* Mark resource for deletion in collection 
     
    129143} 
    130144 
    131  
    132  
     145/* folding sections */ 
     146 
     147function foldToggle(here){ 
     148    if ($(here).hasClass('folded')){         
     149        $(here).removeClass('folded').addClass('unfolded'); 
     150        $('div.folding_area').fadeIn(); 
     151    } else { 
     152        $(here).removeClass('unfolded').addClass('folded'); 
     153        $('div.folding_area').fadeOut(); 
     154    } 
     155    return 0 
     156} 
    133157 
    134158/* Exercise template 
     
    257281    item=data.responseData.feed.entries[0]; 
    258282    pd= new Date(Date.parse(item.publishedDate)); 
    259     html='<b><a href="'+item.link+'">'+item.title+'</a></b> ('+pd.getFullYear()+'-'+pd.getMonth()+'-'+pd.getDate()+')'; 
     283    html='<a href="'+item.link+'">'+item.title+'</a> ('+pd.getFullYear()+'-'+pd.getMonth()+'-'+pd.getDate()+')'; 
    260284    $("span#title_from_blog").html(html);                
    261285 }); 
     
    283307} 
    284308 
     309/* Advanced search */ 
     310function all_types_toggle(obj){ 
     311    if(obj.checked) { 
     312        $('input#lr_cb').attr('checked',0); 
     313        $('td#content_cb_sheet input').attr('checked',1); 
     314        $('td#methods_cb_sheet input').attr('checked',1); 
     315        $('td#tools_cb_sheet input').attr('checked',1); 
     316        $('td#community_cb_sheet input').attr('checked',1); 
     317    } 
     318} 
     319 
     320function lr_types_toggle(obj){ 
     321    if(obj.checked) { 
     322        $('input#all_cb').attr('checked',0); 
     323        $('td#content_cb_sheet input').attr('checked',1); 
     324        $('td#methods_cb_sheet input').attr('checked',1); 
     325        $('td#tools_cb_sheet input').attr('checked',1); 
     326        $('td#community_cb_sheet input').attr('checked',0); 
     327    } 
     328} 
     329 
    285330 
    286331/* Livesearch */  
     
    311356        var $cache = {}; 
    312357        var $querytarget = "livesearch_reply"; 
    313         var $querytarget = $form.attr('action').replace(/lemill_search_results$/g,"") + $querytarget; 
     358        var $querytarget = $form.attr('action').replace(/search$/g,"") + $querytarget; 
    314359        var $$result = $form.find('div.LSResult'); 
    315         var $shadow = $form.find('div.LSShadow'); 
    316360        var $path = $form.find('input[name=path]'); 
    317361 
     
    332376            // shows the result 
    333377            $$result.show(); 
    334             $shadow.html($data); 
     378            $$result.html($data); 
     379            //$shadow.html($data); 
    335380        }; 
    336381 
     
    349394            // Do nothing as long as we have less then two characters -  
    350395            // the search results makes no sense, and it's harder on the server. 
    351             if ($inputnode.value.length < 2) { 
     396            if ($inputnode.value.length < 1) { 
    352397                _hide(); 
    353398                return; 
     399            } else if ($inputnode.value.length < 3) { 
     400                val='<div class="livesearchContainer">'; 
     401                val+='<div class="LSIEFix"><ul><li>'; 
     402                if ($inputnode.value.length==1) val+=$inputnode.value+'..'; 
     403                if ($inputnode.value.length==2) val+=$inputnode.value+'.'; 
     404                val+='</li></ul></div></div>'; 
     405                _show(val); 
     406                return 
    354407            } 
    355408             
     
    396449        var $timeout = null; 
    397450        var $$result = $form.find('div.LSResult'); 
    398         var $shadow = $form.find('div.LSShadow'); 
    399451 
    400452        function _keyUp() { 
    401453            // select the previous element 
    402             $cur = $shadow.find('li.LSHighlight').removeClass(_LSHighlight); 
    403             $prev = $cur.prev('li'); 
    404             if (!$prev.length) $prev = $shadow.find('li:last'); 
     454            $cur = $$result.find('li.LSHighlight').removeClass(_LSHighlight); 
     455            $prev = $cur.prev(); 
     456            if ($prev.is('hr')) $prev= $prev.prev('li'); 
     457            if (!$prev.length) $prev = $$result.find('li:last'); 
    405458            $prev.addClass(_LSHighlight); 
    406459            return false; 
     
    409462        function _keyDown() { 
    410463            // select the next element 
    411             $cur = $shadow.find('li.LSHighlight').removeClass(_LSHighlight); 
    412             $next = $cur.next('li'); 
    413             if (!$next.length) $next = $shadow.find('li:first'); 
     464            $cur = $$result.find('li.LSHighlight').removeClass(_LSHighlight); 
     465            $next = $cur.next(); 
     466            if ($next.is('hr')) $next= $next.next('li'); 
     467            if (!$next.length) $next = $$result.find('li:first'); 
    414468            $next.addClass(_LSHighlight); 
    415469            return false; 
     
    418472        function _keyEscape() { 
    419473            // hide results window 
    420             $shadow.find('li.LSHighlight').removeClass(_LSHighlight); 
     474            $$result.find('li.LSHighlight').removeClass(_LSHighlight); 
    421475            $$result.hide(); 
    422476        }; 
    423  
     477             
    424478        function _handler($event) { 
    425479            // dispatch to specific functions and handle the search timer 
     
    442496            // check whether a search result was selected with the keyboard 
    443497            // and open it 
    444             var $target = $shadow.find('li.LSHighlight a').attr('href'); 
     498            var $target = $$result.find('li.LSHighlight a').attr('href'); 
    445499            if (!$target) return; 
    446500            window.location = $target; 
     
    470524    jq(function() { 
    471525        // find all search fields and set them up 
    472         jq("#searchGadget,input.portlet-search-gadget").each(_setup); 
     526        jq("#searchGadget").each(_setup); 
    473527    }); 
    474528 
  • trunk/skins/lemill/portlet_add_activity.pt

    r2967 r3052  
    55<div metal:define-macro="portlet"> 
    66 
    7 <div class="tb-portlet"> 
    8     <div class="portlet-title"> 
    9     <a href="#" tal:attributes="href python:test(isAnon, 'login_form','%s/methods/createObject?type_name=Activity' % portal_url)" class="linkonbackground"><img src="images/new_activity.png" alt="" class="smallicon" border="0" tal:attributes="src string:${portal_url}/images/new_activity.png" /> 
     7<div class="portlet-title no_padding portlet grid"> 
     8    <a href="#" tal:attributes="href python:test(isAnon, 'login_form','%s/methods/createObject?type_name=Activity' % portal_url)"><img src="images/new_activity.png" alt="" class="smallicon" border="0" tal:attributes="src string:${portal_url}/images/new_activity.png" /> 
    109    <span i18n:translate="label_new_method">New method</span></a> 
    11     </div> 
    1210</div>                 
    1311 
    14 <div class="tb-portlet" tal:condition="not:isAnon"> 
    15     <div class="portlet-title"> 
    16     <img tal:attributes="src string:${portal_url}/transparent.png" src="transparent.png" alt="" class="smallicon" /> 
    17     <tal:block i18n:translate="heading_my_methods">My methods</tal:block> 
    18     </div> 
     12<div class="portlet grid" tal:condition="not:isAnon"> 
     13    <div class="portlet-title" i18n:translate="heading_my_methods">My methods</div> 
    1914<ul> 
    20     <li><a i18n:domain="plone" i18n:translate="label_published" href="#" tal:attributes="href string:${portal_url}/methods/published">Published</a></li> 
     15    <li><a i18n:domain="plone" i18n:translate="label_published" href="#" tal:attributes="href string:${portal_url}/methods/browse?author=${memberid}">Published</a></li> 
    2116    <li><a i18n:translate="label_collections" href="#" tal:attributes="href string:${context/lemill_usertool/getMemberFolderURL}/collections">Collections</a></li> 
    2217</ul> 
    2318</div> 
    2419 
     20<metal:options use-macro="here/browse_macros/macros/browse_options" /> 
    2521</div> 
    2622</body> 
  • trunk/skins/lemill/portlet_add_community.pt

    r2999 r3052  
    55<div metal:define-macro="portlet"> 
    66 
    7 <div class="tb-portlet" tal:define="irc_link context/lemill_tool/irc_link|nothing" tal:condition="irc_link"> 
    8     <div class="portlet-title"> 
    9     <img src="transparent.png" tal:attributes="src string:${portal_url}/transparent.png" alt="" class="smallicon" /> 
    10     <a class="linkonbackground" href="#" target="_new" tal:attributes="href irc_link" i18n:translate="join_lemill_chat">Join LeMill chat...</a> 
    11     </div> 
     7<div class="portlet-title no_padding portlet grid"> 
     8    <a href="#" tal:attributes="href python:test(isAnon, 'login_form','%s/community/group_create' % portal_url)" class="linkonbackground"><img src="images/new_group.png" alt="" class="smallicon" border="0" tal:attributes="src string:${portal_url}/images/new_group.png" /> 
     9    <span i18n:translate="label_new_group">New group</span></a> 
    1210</div> 
    1311 
    14 <div class="tb-portlet"> 
    15     <div class="portlet-title"> 
    16     <a href="#" tal:attributes="href python:test(isAnon, 'login_form','%s/community/group_create' % portal_url)" class="linkonbackground"><img src="images/new_group.png" alt="" class="smallicon" border="0" tal:attributes="src string:${portal_url}/images/new_group.png" /> 
    17     <span i18n:translate="label_new_group">New group</span></a> 
    18     </div> 
    19 </div>                 
    20  
    2112<tal:block tal:condition="not:isAnon"> 
    22  
    23 <tal:defs define="groups memberfolder/getGroups; 
    24     contacts memberfolder/giveSortedListOfContacts"> 
    25  
    26 <div class="tb-portlet"> 
    27     <div class="portlet-title"> 
    28     <img src="transparent.png" tal:attributes="src string:${portal_url}/transparent.png" alt="" class="smallicon" /> 
    29     <tal:block i18n:translate="heading_my_groups">My groups</tal:block> 
    30     </div> 
    31  
     13<tal:defs define="groups memberfolder/getGroups; contacts memberfolder/giveSortedListOfContacts"> 
     14<div class="portlet grid"> 
     15    <div class="portlet-title" i18n:translate="heading_my_groups">My groups</div> 
    3216        <ul tal:condition="groups"> 
    3317           <tal:loop repeat="group groups"> 
     
    3519                 tal:content="group/Title">PLACEHOLDER</a></li> 
    3620           </tal:loop><a href="#" class="show_less" i18n:translate="show_less">Show less</a><a href="#" class="show_more" i18n:translate="show_more">Show more (<span i18n:name="n" tal:replace="python:len(groups)" />)</a> 
    37         </ul> 
    38      
     21        </ul>     
    3922        <span i18n:translate="text_not_member_of_groups" tal:condition="not:groups"> 
    4023        Not member in any groups 
    41         </span> 
    42      
     24        </span>     
    4325</div> 
    4426 
    45 <div class="tb-portlet"> 
    46     <div class="portlet-title"> 
    47     <img src="transparent.png" tal:attributes="src string:${portal_url}/transparent.png" alt="" class="smallicon" /> 
    48     <tal:block i18n:translate="heading_my_contacts">My contacts</tal:block> 
    49     </div> 
     27<div class="portlet grid"> 
     28    <div class="portlet-title" i18n:translate="heading_my_contacts">My contacts</div> 
    5029        <ul tal:condition="contacts"> 
    5130           <tal:loop repeat="contact contacts"> 
     
    6241 
    6342</tal:block> 
     43<metal:options use-macro="here/browse_macros/macros/browse_options" /> 
    6444 
    6545</div> 
  • trunk/skins/lemill/portlet_add_content.pt

    r2967 r3052  
    55<div metal:define-macro="portlet"> 
    66 
    7 <div class="tb-portlet"> 
    8     <div class="portlet-title"> 
    9     <a href="#" tal:attributes="href python:test(isAnon, 'login_form','%s/content/lemill_content_add' % portal_url)" class="linkonbackground"><img src="images/new_content.png" tal:attributes="src string:${portal_url}/images/new_content.png" alt="" class="smallicon" border="0" /> 
     7<div class="portlet-title no_padding portlet grid"> 
     8    <a href="#" tal:attributes="href python:test(isAnon, 'login_form','%s/content/lemill_content_add' % portal_url)"><img src="images/new_content.png" tal:attributes="src string:${portal_url}/images/new_content.png" alt="" class="smallicon" border="0" /> 
    109    <span i18n:translate="label_new_content">New content</span></a> 
    11     </div> 
    1210</div>                 
    1311 
    1412 
    15 <div class="tb-portlet" tal:condition="not:isAnon"> 
    16     <div class="portlet-title"> 
    17     <img src="transparent.png" tal:attributes="src string:${portal_url}/transparent.png" alt="" class="smallicon" /> 
    18     <tal:block i18n:translate="heading_my_content">My content</tal:block> 
    19     </div> 
     13<div class="portlet grid" tal:condition="not:isAnon"> 
     14    <div class="portlet-title" i18n:translate="heading_my_content">My content</div> 
    2015<ul> 
    21     <li><a i18n:translate="label_drafts" href="#" tal:attributes="href string:${portal_url}/content/drafts">Drafts</a></li> 
    22     <li><a i18n:domain="plone" i18n:translate="label_published" href="#" tal:attributes="href string:${portal_url}/content/published">Published</a></li> 
     16    <li><a i18n:translate="label_drafts" href="#" tal:attributes="href string:${portal_url}/content/browse?state=draft&author=${memberid}">Drafts</a></li> 
     17    <li><a i18n:domain="plone" i18n:translate="label_published" href="#" tal:attributes="href string:${portal_url}/content/browse?state=public&author=${memberid}">Published</a></li> 
    2318    <li><a i18n:translate="label_collections" href="#" tal:attributes="href string:${context/lemill_usertool/getMemberFolderURL}/collections">Collections</a></li> 
    2419</ul> 
    2520</div> 
     21 
     22<metal:options use-macro="here/browse_macros/macros/browse_options" /> 
    2623 
    2724</div> 
  • trunk/skins/lemill/portlet_add_tool.pt

    r2967 r3052  
    55<div metal:define-macro="portlet"> 
    66 
    7 <div class="tb-portlet"> 
    8     <div class="portlet-title"> 
    9     <a href="#" tal:attributes="href python:test(isAnon, 'login_form','%s/tools/createObject?type_name=Tool' % portal_url)" class="linkonbackground"><img src="images/new_tool.png" alt="" class="smallicon" border="0" tal:attributes="src string:${portal_url}/images/new_tool.png"/> 
     7<div class="portlet-title no_padding portlet grid"> 
     8    <a href="#" tal:attributes="href python:test(isAnon, 'login_form','%s/tools/createObject?type_name=Tool' % portal_url)" ><img src="images/new_tool.png" alt="" class="smallicon" border="0" tal:attributes="src string:${portal_url}/images/new_tool.png"/> 
    109    <span i18n:translate="label_new_tool">New tool</span></a> 
    11     </div> 
    12 </div>                 
     10</div> 
    1311 
    14 <div class="tb-portlet" tal:condition="not:isAnon"> 
    15     <div class="portlet-title"> 
    16     <img src="transparent.png" tal:attributes="src string:${portal_url}/transparent.png" alt="" class="smallicon" /> 
    17     <tal:block i18n:translate="heading_my_tools">My tools</tal:block> 
    18     </div> 
     12<div class="portlet grid" tal:condition="not:isAnon"> 
     13    <div class="portlet-title" i18n:translate="heading_my_tools">My tools</div> 
    1914<ul> 
    20     <li><a i18n:domain="plone" i18n:translate="label_published" href="#" tal:attributes="href string:${portal_url}/tools/published">Published</a></li> 
     15    <li><a i18n:domain="plone" i18n:translate="label_published" href="#" tal:attributes="href string:${portal_url}/tools/browse?author=${memberid}">Published</a></li> 
    2116    <li><a i18n:translate="label_collections" href="#" tal:attributes="href string:${context/lemill_usertool/getMemberFolderURL}/collections">Collections</a></li> 
    2217</ul> 
    2318</div> 
    2419 
     20<metal:options use-macro="here/browse_macros/macros/browse_options" /> 
    2521</div> 
    2622</body> 
    2723</html> 
    28  
  • trunk/skins/lemill/portlet_blogpost_actions.pt

    r2470 r3052  
    44<body> 
    55 
    6     <div metal:define-macro="portlet" id="portlet-blogpost-actions"  
    7         tal:define="d python:here.getPortletDetails(here.REQUEST, isAnon, member)"> 
    8  
     6   <div metal:define-macro="portlet" id="portlet-blogpost-actions" tal:define="d python:here.getPortletDetails(here.REQUEST, isAnon, member)"> 
    97    <tal:block metal:use-macro="here/portlet_macros/macros/postCoverImageDiv"/> 
    10  
    11     <tal:block metal:use-macro="here/portlet_macros/macros/postEditDiv"/> 
    12      
    13     </div> 
     8    <tal:block metal:use-macro="here/portlet_macros/macros/postEditDiv"/>     
     9   </div> 
    1410 
    1511</body> 
  • trunk/skins/lemill/portlet_collection_actions.pt

    r3010 r3052  
    33      i18n:domain="lemill"> 
    44<body> 
    5 <div metal:define-macro="portlet" id="portlet-material-actions" tal:define="this_member here/getMemberFolder|nothing;" 
    6 > 
    7  
     5<div metal:define-macro="portlet" id="portlet-material-actions" tal:define="this_member here/getMemberFolder|nothing;"> 
    86<div metal:use-macro="here/portlet_member/macros/memberportrait" /> 
    9  
    10 <div class="tb-portlet" metal:define-macro="edit_div" tal:condition="context/amIOwner"> 
     7<div class="portlet grid" metal:define-macro="edit_div" tal:condition="context/amIOwner"> 
    118    <ul> 
    129        <li> 
     
    1815    </ul> 
    1916</div> 
    20  
    21 <div class="tb-portlet" tal:define="len_collections here/getCollectionsLen" tal:condition="python: not isAnon or len_collections"> 
     17<div class="portlet grid" tal:define="len_collections here/getCollectionsLen" tal:condition="python: not isAnon or len_collections"> 
    2218    <ul> 
    2319        <li tal:condition="not:isAnon"><a href="" tal:attributes="href string:${here_url}/collection_add"><tal:block i18n:translate="label_add_to_collection">Add to collection</tal:block>...</a></li> 
     
    2925    </ul> 
    3026</div> 
    31  
    32 <div class="tb-portlet" tal:condition="python: template.id != 'collection_download'"> 
     27<div class="portlet grid" tal:condition="python: template.id != 'collection_download'"> 
    3328    <ul> 
    3429        <li> 
     
    3732    </ul> 
    3833</div> 
    39  
    4034<tal:embed tal:define="d python:{'embedCode':here.getEmbedCode()}"> 
    4135    <div metal:use-macro="here/portlet_macros/macros/embedDiv" /> 
  • trunk/skins/lemill/portlet_groupblog_actions.pt

    r2470 r3052  
    55<body> 
    66 
    7     <div metal:define-macro="portlet" id="portlet-groupblog-actions"  
    8         tal:define="d python:here.getPortletDetails(here.REQUEST, isAnon, member)"> 
    9  
     7  <div metal:define-macro="portlet" id="portlet-groupblog-actions" tal:define="d python:here.getPortletDetails(here.REQUEST, isAnon, member)"> 
    108    <tal:block metal:use-macro="here/portlet_macros/macros/groupCoverImageDiv"/> 
    11  
    129    <tal:block metal:use-macro="here/portlet_macros/macros/groupEditDiv"/> 
    13  
    1410    <tal:block metal:use-macro="here/portlet_macros/macros/groupMembersDiv"/> 
    15  
    16     <tal:block metal:use-macro="here/portlet_macros/macros/groupResourcesDiv"/> 
    17      
    18     </div> 
     11    <tal:block metal:use-macro="here/portlet_macros/macros/groupResourcesDiv"/>     
     12  </div> 
    1913 
    2014</body> 
  • trunk/skins/lemill/portlet_lemillprintresource_actions.pt

    r2636 r3052  
    44<body> 
    55 
    6 <div metal:define-macro="portlet" id="portlet-material-actions" 
    7         tal:define="d python:here.getPortletDetails(here.REQUEST, isAnon, member)"> 
    8  
    9  
    10 <tal:block metal:use-macro="here/portlet_macros/macros/coverImageDiv"/> 
    11  
    12 <tal:block metal:use-macro="here/portlet_macros/macros/editDiv"/> 
    13  
    14 <tal:block metal:use-macro="here/portlet_macros/macros/collectionsDiv"/> 
    15  
    16 <tal:block metal:use-macro="here/portlet_macros/macros/translationsDiv"/> 
    17  
    18  
    19 </div> 
     6 <div metal:define-macro="portlet" id="portlet-material-actions" tal:define="d python:here.getPortletDetails(here.REQUEST, isAnon, member)"> 
     7    <tal:block metal:use-macro="here/portlet_macros/macros/coverImageDiv"/> 
     8    <tal:block metal:use-macro="here/portlet_macros/macros/editDiv"/> 
     9    <tal:block metal:use-macro="here/portlet_macros/macros/collectionsDiv"/> 
     10    <tal:block metal:use-macro="here/portlet_macros/macros/translationsDiv"/> 
     11 </div> 
    2012</body> 
    2113</html> 
  • trunk/skins/lemill/portlet_lemillreference_actions.pt

    r2461 r3052  
    44<body> 
    55 
    6 <div metal:define-macro="portlet" id="portlet-material-actions" 
    7         tal:define="d python:here.getPortletDetails(here.REQUEST, isAnon, member)"> 
    8  
    9  
    10 <tal:block metal:use-macro="here/portlet_macros/macros/coverImageDiv"/> 
    11  
    12 <tal:block metal:use-macro="here/portlet_macros/macros/editDiv"/> 
    13  
    14 <tal:block metal:use-macro="here/portlet_macros/macros/collectionsDiv"/> 
    15  
    16 <tal:block metal:use-macro="here/portlet_macros/macros/translationsDiv"/> 
    17  
    18  
    19 </div> 
     6 <div metal:define-macro="portlet" id="portlet-material-actions" tal:define="d python:here.getPortletDetails(here.REQUEST, isAnon, member)"> 
     7    <tal:block metal:use-macro="here/portlet_macros/macros/coverImageDiv"/> 
     8    <tal:block metal:use-macro="here/portlet_macros/macros/editDiv"/> 
     9    <tal:block metal:use-macro="here/portlet_macros/macros/collectionsDiv"/> 
     10    <tal:block metal:use-macro="here/portlet_macros/macros/translationsDiv"/> 
     11 </div> 
    2012</body> 
    2113</html> 
  • trunk/skins/lemill/portlet_macros.pt

    r3042 r3052  
    1111 
    1212<tal:coverImage metal:define-macro="coverImageDiv"> 
    13 <div class="tb-portlet"> 
     13<div class="portlet grid"> 
    1414    <p style="text-align: center;">  
    1515     <a href="" tal:condition="d/subView" tal:attributes="href string: ${here_url}/view"> 
     
    4545 
    4646<tal:edit_div metal:define-macro="editDiv"> 
    47 <div class="tb-portlet" tal:condition="d/mainView"> 
     47<div class="portlet grid" tal:condition="d/mainView"> 
    4848    <ul> 
    4949        <li> 
     
    6363    </ul> 
    6464</div> 
    65 <div class="tb-portlet" tal:condition="d/aboutView"> 
     65<div class="portlet grid" tal:condition="d/aboutView"> 
    6666    <ul> 
    6767      <li><a href="" tal:attributes="href d/editMetadataLink"><tal:block i18n:translate="label_edit_about">Edit about</tal:block>...</a></li> 
    6868    </ul> 
    6969</div> 
    70 <div class="tb-portlet" tal:condition="d/versionView"> 
     70<div class="portlet grid" tal:condition="d/versionView"> 
    7171    <ul> 
    7272        <li><a href="" i18n:translate="label_restore_this_version"  tal:attributes="href string:${here_url}/restoreAVersion?timestamp=${d/versionView}">Restore this version</a></li> 
     
    8282<tal:source_file_div metal:define-macro="sourceFileDiv"> 
    8383<div tal:condition="python:context.canIEditSource()" > 
    84     <div class="tb-portlet" tal:condition="d/mainView"> 
     84    <div class="portlet grid" tal:condition="d/mainView"> 
    8585        <span id="deltext" i18n:translate="source_file_delete_confirmation" style="display:none">Are you sure you want to delete source file?</span> 
    8686        <ul> 
     
    102102 
    103103<tal:tags_div metal:define-macro="tagsDiv"> 
    104     <div class="tb-portlet" tal:define="url_base python:context.getSectionFolder(bottom=True).absolute_url()"> 
     104    <div class="portlet grid" tal:define="url_base python:context.getSectionFolder(bottom=True).absolute_url()"> 
    105105        <ul> 
    106106           <tal:loopy repeat="tag d/tags"><a href="" tal:attributes="href python:url_base+'/tags?tag='+tag" tal:content="tag" /><span tal:condition="not:repeat/tag/end" tal:omit-tag="">, </span></tal:loopy> 
     
    121121 
    122122<tal:collections_div metal:define-macro="collectionsDiv"> 
    123 <div class="tb-portlet" tal:condition="d/showCollections"> 
     123<div class="portlet grid" tal:condition="d/showCollections"> 
    124124    <ul> 
    125125        <li tal:condition="not:isAnon"><a href="" tal:attributes="href string:${here_url}/collection_add"><tal:block i18n:translate="label_add_to_collection">Add to collection</tal:block>...</a></li> 
     
    139139 
    140140<tal:branch_div metal:define-macro="branchesDiv"> 
    141 <div class="tb-portlet" tal:condition="d/showBranches"> 
     141<div class="portlet grid" tal:condition="d/showBranches"> 
    142142    <ul> 
    143143        <tal:branch repeat="resource d/branches"> 
     
    159159 
    160160<tal:translate_div metal:define-macro="translationsDiv"> 
    161 <div class="tb-portlet" tal:condition="d/showTranslations"> 
     161<div class="portlet grid" tal:condition="d/showTranslations"> 
    162162    <ul> 
    163163        <li><a href="" tal:attributes="href d/translateLink"><tal:block i18n:translate="label_translate">Translate</tal:block>...</a></li> 
     
    179179 
    180180<tal:views_div metal:define-macro="viewsDiv"> 
    181 <div class="tb-portlet" tal:condition="d/hasViews"> 
     181<div class="portlet grid" tal:condition="d/hasViews"> 
    182182    <ul> 
    183183        <li tal:condition="d/studentViewLink"><a i18n:translate="label_student_view" tal:attributes="href d/studentViewLink">Student view</a></li> 
     
    192192 
    193193<tal:embed_div metal:define-macro="embedDiv"> 
    194 <div class="tb-portlet" tal:condition="d/embedCode"> 
     194<div class="portlet grid" tal:condition="d/embedCode"> 
    195195    <ul style="list-style:none"> 
    196196        <li> 
     
    219219 
    220220<tal:group_cover_image metal:define-macro="groupCoverImageDiv"> 
    221 <div class="tb-portlet"> 
     221<div class="portlet grid"> 
    222222    <p style="text-align: center;">  
    223223      <img src="images/default_groupblog.png" tal:attributes="src here/getCoverImageURL; alt python:here.meta_type" style="padding: 39px 0px 29px 0px;" tal:condition="d/mainView" />      
     
    236236 
    237237<tal:group_edit_div metal:define-macro="groupEditDiv"> 
    238 <div class="tb-portlet" tal:condition="d/mainView"> 
    239     <div class="portlet-title"> 
    240     <img src="transparent.png" tal:attributes="src string:${portal_url}/transparent.png" alt="" class="smallicon" /> 
    241     <tal:block i18n:domain="plone" i18n:translate="heading_actions">Actions</tal:block> 
    242     </div> 
     238<div class="portlet grid" tal:condition="d/mainView"> 
     239    <div class="portlet-title" i18n:domain="plone" i18n:translate="heading_actions">Actions</div> 
    243240    <ul> 
    244241        <li tal:condition="d/manageGroup"><a i18n:translate="label_manage_members" href="edit">Manage group</a></li> 
     
    252249groupMembers 
    253250<tal:group_members_div metal:define-macro="groupMembersDiv"> 
    254 <div class="tb-portlet" tal:condition="d/groupMembers"> 
    255     <div class="portlet-title"> 
    256     <img src="transparent.png" tal:attributes="src string:${portal_url}/transparent.png" alt="" class="smallicon" /> 
    257     <tal:block i18n:translate="heading_members">Members</tal:block> 
    258     </div> 
    259  
     251<div class="portlet grid" tal:condition="d/groupMembers"> 
     252    <div class="portlet-title" i18n:translate="heading_members">Members</div> 
    260253    <ul> 
    261254     <tal:loop repeat="memberdata d/groupMembers"> 
     
    273266groupResources 
    274267<tal:group_resources_div metal:define-macro="groupResourcesDiv"> 
    275 <div class="tb-portlet" tal:define="amounts_dict d/groupResources"> 
    276     <div class="portlet-title"> 
    277         <img src="transparent.png" tal:attributes="src string:${portal_url}/transparent.png" alt="" class="smallicon" /> 
    278         <tal:block i18n:translate="heading_groups_resources">Group's resources</tal:block> 
    279     </div> 
     268<div class="portlet grid" tal:define="amounts_dict d/groupResources"> 
     269    <div class="portlet-title" i18n:translate="heading_groups_resources">Group's resources</div> 
    280270    <ul> 
    281271        <li> 
     
    303293 
    304294<tal:post_cover_image metal:define-macro="postCoverImageDiv"> 
    305 <div class="tb-portlet"> 
     295<div class="portlet grid"> 
    306296    <p style="text-align: center;" tal:condition="d/groupURL">  
    307297     <a href="" tal:attributes="href d/groupURL"> 
     
    317307 
    318308<tal:post_edit_div metal:define-macro="postEditDiv"> 
    319 <div class="tb-portlet" tal:condition="context/canIEdit"> 
    320     <div class="portlet-title"> 
    321     <img src="transparent.png" tal:attributes="src string:${portal_url}/transparent.png" alt="" class="smallicon" /> 
    322     <tal:block i18n:domain="plone" i18n:translate="heading_actions">Actions</tal:block> 
    323     </div> 
     309<div class="portlet grid" tal:condition="context/canIEdit"> 
     310    <div class="portlet-title" i18n:domain="plone" i18n:translate="heading_actions">Actions</div> 
    324311    <ul> 
    325312        <li tal:condition="d/editPost"> 
     
    342329 
    343330<tal:mf_cover_image metal:define-macro="memberImageDiv"> 
    344 <div class="tb-portlet"> 
     331<div class="portlet grid"> 
    345332    <p style="text-align: center;" >  
    346333      <img src="images/default_memberfolder.png" tal:condition="d/mainView" tal:attributes="src d/memberImageURL; alt context/getNicename" style="padding: 39px 0px 29px 0px;" /> 
     
    356343 
    357344<tal:mf_contact_control metal:define-macro="memberContactControl"> 
    358 <div class="tb-portlet" tal:condition="d/contactControls"> 
     345<div class="portlet grid" tal:condition="d/contactControls"> 
    359346    <ul> 
    360347        <li tal:condition="d/inviteToGroup"> 
  • trunk/skins/lemill/portlet_material_actions.pt

    r3013 r3052  
    33      i18n:domain="lemill"> 
    44<body> 
    5     <div metal:define-macro="portlet" id="portlet-material-actions"  
    6         tal:define="d python:here.getPortletDetails(here.REQUEST, isAnon, member)"> 
    7  
    8  
    9 <tal:block metal:use-macro="here/portlet_macros/macros/coverImageDiv"/> 
    10  
    11 <tal:block metal:use-macro="here/portlet_macros/macros/editDiv"/> 
    12  
    13 <tal:block metal:use-macro="here/portlet_macros/macros/tagsDiv" /> 
    14  
    15 <tal:block metal:use-macro="here/portlet_macros/macros/collectionsDiv"/> 
    16  
    17 <tal:block metal:use-macro="here/portlet_macros/macros/branchesDiv"/> 
    18  
    19 <tal:block metal:use-macro="here/portlet_macros/macros/translationsDiv"/> 
    20  
    21 <tal:block metal:use-macro="here/portlet_macros/macros/viewsDiv"/> 
    22  
    23 <tal:block metal:use-macro="here/portlet_macros/macros/embedDiv"/> 
    24  
     5<div metal:define-macro="portlet" id="portlet-material-actions" tal:define="d python:here.getPortletDetails(here.REQUEST, isAnon, member)"> 
     6    <tal:block metal:use-macro="here/portlet_macros/macros/coverImageDiv"/> 
     7    <tal:block metal:use-macro="here/portlet_macros/macros/editDiv"/> 
     8    <tal:block metal:use-macro="here/portlet_macros/macros/tagsDiv" /> 
     9    <tal:block metal:use-macro="here/portlet_macros/macros/collectionsDiv"/> 
     10    <tal:block metal:use-macro="here/portlet_macros/macros/branchesDiv"/> 
     11    <tal:block metal:use-macro="here/portlet_macros/macros/translationsDiv"/> 
     12    <tal:block metal:use-macro="here/portlet_macros/macros/viewsDiv"/> 
     13    <tal:block metal:use-macro="here/portlet_macros/macros/embedDiv"/> 
    2514</div> 
    2615</body> 
  • trunk/skins/lemill/portlet_member.pt

    r3031 r3052  
    88 
    99            <div metal:define-macro="memberportrait" tal:omit-tag=""> 
    10             <div class="tb-portlet" 
     10            <div class="portlet grid" 
    1111                tal:define="portrait this_member/getCoverImage; 
    1212                            portrait_url portrait/absolute_url | string:images/default_member.png;"> 
    13                 <p style="text-align: center;"> 
    14             <a href="" tal:attributes="href this_member/absolute_url"> 
    15                 <img src="" 
    16                 alt="" 
    17                 style="padding: 39px 0px 29px 0px;" 
    18                 tal:attributes="src portrait_url" /> 
    19             </a> 
    20                 </p> 
     13              <p style="text-align: center;"> 
     14                <a href="" tal:attributes="href this_member/absolute_url"> 
     15                    <img src="" 
     16                    alt="" 
     17                    style="padding: 39px 0px 29px 0px;" 
     18                    tal:attributes="src portrait_url" /> 
     19                </a> 
     20              </p> 
    2121            </div> 
    2222            </div> 
    23  
    24              <div class="tb-portlet" tal:condition="python:not isAnon and context.getMemberId()!=memberid"> 
     23             <div class="portlet grid" tal:condition="python:not isAnon and context.getMemberId()!=memberid"> 
    2524                <ul tal:define="groups memberfolder/getGroups; 
    2625                    show_remove here/showRemoveContactLink"> 
     
    4039                </ul> 
    4140            </div> 
    42  
    43             <div class="tb-portlet" tal:define="groups this_member/getGroups"> 
    44                 <div class="portlet-title"> 
    45                     <img src="transparent.png" tal:attributes="src string:${portal_url}/transparent.png" alt="" class="smallicon" /> 
    46                     <tal:block i18n:translate="heading_groups">Groups</tal:block> 
    47                 </div> 
     41            <div class="portlet grid" tal:define="groups this_member/getGroups"> 
     42                <div class="portlet-title" i18n:translate="heading_groups">Groups</div> 
    4843                <ul tal:condition="groups"> 
    4944                    <tal:loop repeat="groupish groups"> 
     
    5853                </span> 
    5954            </div> 
    60  
    61             <div class="tb-portlet"> 
    62                 <div class="portlet-title"> 
    63                     <img src="transparent.png" tal:attributes="src string:${portal_url}/transparent.png" alt="" class="smallicon" /> 
    64                     <tal:block i18n:translate="heading_contacts">Contacts</tal:block> 
    65                 </div> 
    66  
     55            <div class="portlet grid"> 
     56                <div class="portlet-title" i18n:translate="heading_contacts">Contacts</div> 
    6757                <span tal:define="contacts this_member/giveSortedListOfContacts"> 
    6858                    <ul tal:condition="contacts"> 
     
    7969                </span> 
    8070            </div> 
    81  
    82             <div class="tb-portlet" tal:define="creator here/Creator;  
     71            <div class="portlet grid" tal:define="creator here/Creator;  
    8372                amounts_dict python:this_member.getResources(creator, n=True, as_dict=True); 
    8473                creator_url this_member/absolute_url; 
    8574                "> 
    86                 <div class="portlet-title"> 
    87                     <img src="transparent.png" tal:attributes="src string:${portal_url}/transparent.png" alt="" class="smallicon" /> 
    88                     <tal:block i18n:translate="heading_portfolio_portlet">Full portfolio</tal:block> 
    89                 </div> 
    90  
     75                <div class="portlet-title" i18n:translate="heading_portfolio_portlet">Full portfolio</div> 
    9176                <ul> 
    9277                    <li> 
     
    10893                        <a i18n:translate="label_tag_cloud" href="portfolio" tal:attributes="href python:creator_url+'/portfolio'">Tag cloud</a> 
    10994                    </li> 
    110  
    111                     
    11295                </ul> 
    11396           </div> 
  • trunk/skins/lemill/portlet_piece_actions.pt

    r2650 r3052  
    33      i18n:domain="lemill"> 
    44<body> 
    5 <div metal:define-macro="portlet" id="portlet-material-actions"  
    6         tal:define="d python:here.getPortletDetails(here.REQUEST, isAnon, member)"> 
    7  
    8  
    9 <tal:block metal:use-macro="here/portlet_macros/macros/coverImageDiv"/> 
    10  
    11 <tal:block metal:use-macro="here/portlet_macros/macros/editDiv"/> 
    12  
    13 <tal:block metal:use-macro="here/portlet_macros/macros/sourceFileDiv"/> 
    14  
    15 <tal:block metal:use-macro="here/portlet_macros/macros/collectionsDiv"/> 
    16  
     5<div metal:define-macro="portlet" id="portlet-material-actions" tal:define="d python:here.getPortletDetails(here.REQUEST, isAnon, member)"> 
     6    <tal:block metal:use-macro="here/portlet_macros/macros/coverImageDiv"/> 
     7    <tal:block metal:use-macro="here/portlet_macros/macros/editDiv"/> 
     8    <tal:block metal:use-macro="here/portlet_macros/macros/sourceFileDiv"/> 
     9    <tal:block metal:use-macro="here/portlet_macros/macros/collectionsDiv"/> 
    1710</div> 
    1811</body> 
  • trunk/skins/lemill/portlet_tool_actions.pt

    r2461 r3052  
    33      i18n:domain="lemill"> 
    44<body> 
    5 <div metal:define-macro="portlet" id="portlet-material-actions"  
    6         tal:define="d python:here.getPortletDetails(here.REQUEST, isAnon, member)"> 
    7  
    8  
    9 <tal:block metal:use-macro="here/portlet_macros/macros/coverImageDiv"/> 
    10  
    11 <tal:block metal:use-macro="here/portlet_macros/macros/editDiv"/> 
    12  
    13 <tal:block metal:use-macro="here/portlet_macros/macros/collectionsDiv"/> 
    14  
    15 <tal:block metal:use-macro="here/portlet_macros/macros/translationsDiv"/> 
    16 </div> 
     5 <div metal:define-macro="portlet" id="portlet-material-actions" tal:define="d python:here.getPortletDetails(here.REQUEST, isAnon, member)"> 
     6    <tal:block metal:use-macro="here/portlet_macros/macros/coverImageDiv"/> 
     7    <tal:block metal:use-macro="here/portlet_macros/macros/editDiv"/> 
     8    <tal:block metal:use-macro="here/portlet_macros/macros/collectionsDiv"/> 
     9    <tal:block metal:use-macro="here/portlet_macros/macros/translationsDiv"/> 
     10 </div> 
    1711</body> 
    1812</html> 
  • trunk/skins/lemill/resource_list_macro.pt

    r3035 r3052  
    113113    <tal:defs define="obj_url obj/getURL | obj/absolute_url; 
    114114            showAuthor python:obj_state != 'draft'; 
    115             obj_url python:test(use_view_action, '%s/view' % obj_url, obj_url); 
    116115            HasCoverImage obj/getHasCoverImage | python:None; 
    117116            name obj/Title | obj/getId; 
    118117            creator obj/Creator; 
    119             modDate obj/ModificationDate; 
    120118            authors obj/listCreators; 
    121119            lang obj/Language; 
     
    236234</metal:block> 
    237235 
     236<metal:block define-macro="result_list"> 
     237<ul tal:define="processed_batch python:here.portal_catalog.buildResultsFromBatch(batch);" class="result_list"> 
     238    <li tal:repeat="item processed_batch"> 
     239        <div class="list_cover_box">&nbsp;<a href="" tal:attributes="href item/url; title item/title"> 
     240            <img src="" title="" valign="middle" tal:attributes="src item/coverimage_url; title item/title; alt item/title" /> 
     241        </a>&nbsp;</div> 
     242        <div class="list_data_box"> 
     243            <p><a href="" tal:attributes="href item/url" tal:content="item/title" >Title</a></p> 
     244            <p i18n:translate="" tal:content="item/readable_type">Resource type</p> 
     245            <p tal:condition="item/authors"><tal:tr i18n:translate="label_authors">Authors</tal:tr>: <tal:block tal:repeat="author item/authors"><a href="" tal:attributes="href python:author[1]" tal:content="python:author[0]">name</a><tal:block condition="not:repeat/author/end">, </tal:block></tal:block></p> 
     246            <p tal:condition="item/country"><tal:tr i18n:translate="label_location">Location</tal:tr>: <a href="" tal:content="item/country" tal:attributes="href item/country_link">Country</a></p> 
     247            <p tal:condition="item/tags"><tal:tr i18n:translate="label_tags">Tags</tal:tr>: <tal:block tal:repeat="tag item/tags"><a href="" tal:attributes="href python:tag[1]" tal:content="python:tag[0]">tag</a><tal:block condition="not:repeat/tag/end">, </tal:block></tal:block></p> 
     248            <p tal:condition="item/language"><tal:tr i18n:translate="label_language">Language</tal:tr>: <a href="" tal:content="item/language" tal:attributes="href item/language_link">Country</a></p> 
     249        </div> 
     250    </li>  
     251</ul> 
     252<div class="clear"></div> 
     253</metal:block> 
    238254 
    239255</body> 
  • trunk/skins/lemill/script_objectCount.py

    r3004 r3052  
    11 
    2 return {'n_teachers':len(context.getSearchObject(portal_type = 'MemberFolder', getState = 'public')), 
    3 'n_contents':len(context.getSearchObject(portal_type = context.content.getMaterialTypes(), getState = 'public')), 
    4 'n_tools':len(context.getSearchObject(portal_type = context.content.getToolsTypes(), getState = 'public')), 
    5 'n_methods':len(context.getSearchObject(portal_type = context.content.getActivityTypes(), getState = 'public'))} 
     2# this is in external script so that the result can be cached 
     3return context.lemill_tool.getLeMillStats() 
  • trunk/skins/lemill/setLang.py

    r2871 r3052  
    99## 
    1010REQUEST=context.REQUEST 
    11 url=REQUEST.get('URL1') 
     11ref=REQUEST.HTTP_REFERER 
    1212if lang: 
    1313    context.portal_languages.setLanguageCookie(lang, REQUEST, None) 
    14     if param: 
    15         param = param.replace('_and_', '&') 
    16         return REQUEST.RESPONSE.redirect('?'.join((url,param))) 
    17     return REQUEST.RESPONSE.redirect(url) 
     14return REQUEST.RESPONSE.redirect(ref) 
Note: See TracChangeset for help on using the changeset viewer.