Changeset 2983
- Timestamp:
- 01/05/08 09:13:38 (11 months ago)
- Files:
-
- trachacksplugin/0.11/trachacks/htdocs/css/trachacks.css (modified) (1 diff)
- trachacksplugin/0.11/trachacks/htdocs/js/trachacks.js (modified) (1 diff)
- trachacksplugin/0.11/trachacks/templates/hacks_view.html (modified) (1 diff)
- trachacksplugin/0.11/trachacks/trachacks.py (modified) (6 diffs)
Legend:
- Unmodified
- Added
- Removed
- Modified
- Copied
- Moved
trachacksplugin/0.11/trachacks/htdocs/css/trachacks.css
r2979 r2983 1 1 .tagcloud li:after { content: " "; } 2 2 .tagcloud li.last:after { content: ""; } 3 4 .newhack { 5 width: 850px; 6 } 7 8 .newhack input[type="text"] { 9 width: 65%; 10 } 11 12 .newhack dt { 13 font-weight: bold; 14 } 15 16 .newhack dd { 17 margin: 1em; 18 margin-top: 0em; 19 } 20 21 .info { 22 opacity: 0.0; 23 } 24 25 .newhack div.info { 26 width: 40ex; 27 font-size: xx-small; 28 float: right; 29 clear: both; 30 background: #b0ffb0; 31 border: 2px solid #40e040; 32 margin: 0em; 33 padding: 0.2em 1em; 34 } trachacksplugin/0.11/trachacks/htdocs/js/trachacks.js
r2979 r2983 1 1 $(document).ready(function() { 2 // $('.desc').toggle(); 2 // Move the label for each field into the info block. 3 $('.info').each(function() { 4 var info = this; 5 var fieldid = info.id.slice(0, -4); 6 7 $('label[@for="' + fieldid + '"]').each(function() { 8 var title = $(this).text(); 9 10 $(info).prepend('<strong>' + title + '</strong>'); 11 }); 12 }); 13 14 // Fade all the info blocks out then focus the #name field 15 $('.info').fadeTo('fast', 0.4, function() { 16 $('#name').focus(); 17 }); 18 19 20 // Handle focus/blur of input fields 21 $('input, textarea').focus(function() { 22 var id = '#' + this.id + 'info'; 23 24 $(id).fadeTo('slow', 1.0); 25 }); 26 $('input, textarea').blur(function() { 27 $('#' + this.id + 'info').fadeTo('slow', 0.4); 28 }); 3 29 }); trachacksplugin/0.11/trachacks/templates/hacks_view.html
r2979 r2983 14 14 <body> 15 15 <div id="content" class="tags"> 16 <form id="query" action="${href.hacks()}"method="get">16 <form id="query" method="get"> 17 17 <div> 18 18 <input type="text" id="tag-query" name="q" size="40" accesskey="t" 19 value="${ tag_query}"/>19 value="${query}"/> 20 20 <input type="submit" value="Filter Hacks"/> 21 21 </div> 22 <div py:if=" tag_query_error" id="query-error">23 <strong>Error:</strong> ${ tag_query_error}22 <div py:if="query_error" id="query-error"> 23 <strong>Error:</strong> ${query_error} 24 24 </div> 25 25 <div> 26 Showing <strong>${limit}</strong> results. 26 <ul> 27 <li>Showing <strong>${limit_message}</strong> results.</li> 28 </ul> 27 29 </div> 28 30 </form> 29 31 30 32 <div id="tag_body"> 31 <h1 py:if="tag_title">${tag_title}</h1> 32 ${tag_body} 33 ${body} 33 34 </div> 34 35 </div> trachacksplugin/0.11/trachacks/trachacks.py
r2979 r2983 20 20 from tractags.api import TagSystem 21 21 from tractags.macros import render_cloud 22 from tractags.query import Query 22 23 from tracvote import VoteSystem 23 24 from genshi.builder import tag as builder … … 50 51 'Default maximum number of hacks to display.') 51 52 52 path_match = re.compile(r'/hacks/?( .+)?')53 path_match = re.compile(r'/hacks/?(new|cloud|list)?') 53 54 title_extract = re.compile(r'=\s+([^=]*)=', re.MULTILINE | re.UNICODE) 55 page_split = re.compile(r'(\w+)', re.I | re.UNICODE) 54 56 55 57 # IRequestHandler methods … … 72 74 tag_system.query(req, 'realm:wiki release')]) 73 75 74 hacks = self.fetch_hacks(req, data, types) 76 data['types'] = types 77 data['releases'] = releases 78 79 if view != 'new': 80 hacks = self.fetch_hacks(req, data, types) 75 81 76 82 add_stylesheet(req, 'tags/css/tractags.css') … … 78 84 add_script(req, 'hacks/js/trachacks.js') 79 85 80 views = ['cloud', 'list' ]86 views = ['cloud', 'list', 'new'] 81 87 for v in views: 82 88 if v != view: 83 add_ctxtnav(req, builder.a(v.title(), href=req.href.hacks(v))) 89 if v != 'new': 90 args = req.args 91 else: 92 args = {} 93 add_ctxtnav(req, builder.a(v.title(), 94 href=req.href.hacks(v, **args))) 84 95 else: 85 96 add_ctxtnav(req, v.title()) 86 if view == 'cloud': 87 return self.render_cloud(req, data, hacks) 88 elif view == 'list': 97 if view == 'list': 89 98 return self.render_list(req, data, hacks) 90 91 def fetch_hacks(self, req, data, types): 92 """Return a list of hacks in the form 93 94 [votes, rank, resource, tags, title] 95 """ 96 tag_system = TagSystem(self.env) 97 vote_system = VoteSystem(self.env) 98 hacks = [] 99 global limit 100 ALL = 9999 101 limit = req.args.get('limit', self.limit) 102 103 # Custom tag query modifiers 104 def top_modifier(name, node, context): 105 """top:<n> Only show the top N results.""" 106 global limit 107 if node.value == 'all': 108 limit = ALL 109 return True 110 try: 111 assert node.type == node.TERM 112 limit = int(node.value) 113 except (AssertionError, ValueError): 114 raise TracError('top: expects an integer') 115 return True 116 117 data['tag_query'] = req.args.get('q', '') 118 119 # Get list of hacks from tag system 120 query = 'realm:wiki (%s)' % ' or '.join(types) 121 if req.args.get('q'): 122 query += ' (' + req.args.get('q', '') + ')' 123 self.env.log.debug('Hack query: %s', query) 124 attribute_handlers={'top': top_modifier,} 125 try: 126 tagged = list(tag_system.query(req, query, 127 attribute_handlers=attribute_handlers)) 128 except TracError, e: 129 tagged = [] 130 tagged = tag_system.query(req, 'realm:wiki (#s)' % ' or '.join(types), 131 attribute_handlers=attribute_handlers) 132 data['tag_query_error'] = str(e) 133 134 self.env.log.debug(limit) 135 if limit != ALL: 136 data['limit'] = 'top %s' % limit 137 else: 138 data['limit'] = 'all' 139 140 # Build hacks list 141 for resource, tags in tagged: 142 page = WikiPage(self.env, resource.id) 143 _, count, _ = vote_system.get_vote_counts(resource) 144 match = self.title_extract.search(page.text) 145 count_string = pluralise(count, 'vote') 146 if match: 147 title = '%s (%s)' % (match.group(1).strip(), count_string) 148 else: 149 title = '%s' % count_string 150 hacks.append([count, None, resource, tags, title]) 151 152 # Rank 153 hacks = sorted(hacks, key=lambda i: -i[0])[:limit] 154 for i, hack in enumerate(hacks): 155 hack[1] = i 156 return hacks 99 elif view == 'new': 100 return self.render_new(req, data) 101 return self.render_cloud(req, data, hacks) 102 103 def render_new(self, req, data): 104 add_script(req, 'common/js/wikitoolbar.js') 105 return 'hacks_new.html', data, None 157 106 158 107 def render_list(self, req, data, hacks): … … 163 112 ' - ', title) 164 113 ul(li) 165 data[' tag_body'] = ul114 data['body'] = ul 166 115 return 'hacks_view.html', data, None 167 116 … … 180 129 181 130 cloud_hacks = dict([(hack[2].id, hack[0]) for hack in hacks]) 182 data[' tag_body'] = render_cloud(self.env, req, cloud_hacks, link_renderer)131 data['body'] = render_cloud(self.env, req, cloud_hacks, link_renderer) 183 132 184 133 return 'hacks_view.html', data, None 134 135 def fetch_hacks(self, req, data, types): 136 """Return a list of hacks in the form 137 138 [votes, rank, resource, tags, title] 139 """ 140 tag_system = TagSystem(self.env) 141 vote_system = VoteSystem(self.env) 142 143 tagged = tag_system.query(req, 'realm:wiki (' + ' or '.join(types) + ')') 144 145 # Limit 146 try: 147 limit = int(req.args.get('limit', self.limit)) 148 data['limit_message'] = 'top %s' % limit 149 except ValueError: 150 data['limit_message'] = 'all' 151 limit = 9999 152 data['limit'] = limit 153 154 # Query 155 q = req.args.get('q', '') 156 data['query'] = q 157 query = Query(q.lower()) 158 159 # Build hacks list 160 hacks = [] 161 for resource, tags in tagged: 162 page = WikiPage(self.env, resource.id) 163 if q: 164 text = page.name.lower() + page.text.lower() + ' '.join(tags) 165 if not query(text): 166 continue 167 _, count, _ = vote_system.get_vote_counts(resource) 168 match = self.title_extract.search(page.text) 169 count_string = pluralise(count, 'vote') 170 if match: 171 title = '%s (%s)' % (match.group(1).strip(), count_string) 172 else: 173 title = '%s' % count_string 174 hacks.append([count, None, resource, tags, title]) 175 176 # Rank 177 total_hack_count = len(hacks) 178 hacks = sorted(hacks, key=lambda i: -i[0])[:limit] 179 180 # Navigation 181 if len(hacks) >= limit: 182 add_ctxtnav(req, builder.a('More', href='?limit=%i&q=%s' % (limit + 10, q))) 183 limit = len(hacks) 184 data['limit'] = data['limit_message'] = limit 185 else: 186 add_ctxtnav(req, 'More') 187 if q or limit != self.limit: 188 add_ctxtnav(req, builder.a('Default', href='?limit=%i' % self.limit)) 189 else: 190 add_ctxtnav(req, 'Default') 191 if total_hack_count > limit: 192 add_ctxtnav(req, builder.a('All', href='?limit=all&q=' + q)) 193 else: 194 add_ctxtnav(req, 'All') 195 if limit > 10: 196 limit = min(limit, len(hacks)) 197 add_ctxtnav(req, builder.a('Less', href='?limit=%i&q=%s' % (limit - 10 > 0 and limit - 10 or 0, q))) 198 else: 199 add_ctxtnav(req, 'Less') 200 for i, hack in enumerate(hacks): 201 hack[1] = i 202 return hacks 185 203 186 204 # INavigationContributor methods
