comparison MoinMoin/themes/__init__.py @ 2519:b942154b2d74

merged bootstrap and main repo
author Thomas Waldmann <tw AT waldmann-edv DOT de>
date Sun, 02 Feb 2014 17:14:23 +0100
parents f1d470ade3c0 7b7e07bb6f8a
children 07f3ccfdea45
comparison
equal deleted inserted replaced
2518:61884a46ae68 2519:b942154b2d74
20 from MoinMoin import log 20 from MoinMoin import log
21 logging = log.getLogger(__name__) 21 logging = log.getLogger(__name__)
22 22
23 from MoinMoin.i18n import _, L_, N_ 23 from MoinMoin.i18n import _, L_, N_
24 from MoinMoin import wikiutil, user 24 from MoinMoin import wikiutil, user
25 from MoinMoin.constants.keys import USERID, ADDRESS, HOSTNAME 25 from MoinMoin.constants.keys import USERID, ADDRESS, HOSTNAME, REVID, ITEMID, NAME_EXACT
26 from MoinMoin.constants.namespaces import NAMESPACE_DEFAULT, NAMESPACE_USERPROFILES, NAMESPACE_ALL
26 from MoinMoin.search import SearchForm 27 from MoinMoin.search import SearchForm
27 from MoinMoin.util.interwiki import split_interwiki, getInterwikiHome, is_local_wiki, is_known_wiki, url_for_item 28 from MoinMoin.util.interwiki import split_interwiki, getInterwikiHome, is_local_wiki, is_known_wiki, url_for_item, CompositeName, split_fqname
28 from MoinMoin.util.crypto import cache_key 29 from MoinMoin.util.crypto import cache_key
29 from MoinMoin.util.forms import make_generator 30 from MoinMoin.util.forms import make_generator
30 from MoinMoin.util.clock import timed 31 from MoinMoin.util.clock import timed
31 from MoinMoin.util.mime import Type 32 from MoinMoin.util.mime import Type
32 33
215 'frontend.backrefs': "icon-share", 216 'frontend.backrefs': "icon-share",
216 'special.comments': "icon-comment", 217 'special.comments': "icon-comment",
217 'special.transclusions': "icon-edit", } 218 'special.transclusions': "icon-edit", }
218 return icon 219 return icon
219 220
220 def location_breadcrumbs(self, item_name): 221 def location_breadcrumbs(self, fqname):
221 """ 222 """
222 Assemble the location using breadcrumbs (was: title) 223 Assemble the location using breadcrumbs (was: title)
223 224
224 :rtype: list 225 :rtype: list
225 :returns: location breadcrumbs items in tuple (segment_name, item_name, exists) 226 :returns: location breadcrumbs items in tuple (segment_name, fq_name, exists)
226 """ 227 """
227 breadcrumbs = [] 228 breadcrumbs = []
228 current_item = '' 229 current_item = ''
230 if not isinstance(fqname, CompositeName):
231 fqname = split_fqname(fqname)
232 if fqname.field != NAME_EXACT:
233 return [(fqname, fqname, bool(self.storage.get_item(**fqname.query)))]
234 namespace = fqname.namespace
235 fq_current = CompositeName(u'', NAME_EXACT, namespace)
236 fq_segment = CompositeName(u'', NAME_EXACT, namespace or '~')
237 breadcrumbs.append((fq_segment, fq_current, False))
238 item_name = fqname.value
239 if not item_name:
240 return breadcrumbs
229 for segment in item_name.split('/'): 241 for segment in item_name.split('/'):
230 current_item += segment 242 current_item += segment
231 breadcrumbs.append((segment, current_item, self.storage.has_item(current_item))) 243 fq_current = CompositeName(namespace, NAME_EXACT, current_item)
244 fq_segment = CompositeName(namespace, NAME_EXACT, segment)
245 breadcrumbs.append((fq_segment, fq_current, bool(self.storage.get_item(**fq_current.query))))
232 current_item += '/' 246 current_item += '/'
233 return breadcrumbs 247 return breadcrumbs
234 248
235 def path_breadcrumbs(self): 249 def path_breadcrumbs(self):
236 """ 250 """
241 """ 255 """
242 user = self.user 256 user = self.user
243 breadcrumbs = [] 257 breadcrumbs = []
244 trail = user.get_trail() 258 trail = user.get_trail()
245 for interwiki_item_name in trail: 259 for interwiki_item_name in trail:
246 wiki_name, namespace, item_name = split_interwiki(interwiki_item_name) 260 wiki_name, namespace, field, item_name = split_interwiki(interwiki_item_name)
261 fqname = CompositeName(namespace, field, item_name)
247 err = not is_known_wiki(wiki_name) 262 err = not is_known_wiki(wiki_name)
248 href = url_for_item(item_name, namespace=namespace, wiki_name=wiki_name) 263 href = url_for_item(wiki_name=wiki_name, **fqname.split)
249 if is_local_wiki(wiki_name): 264 if is_local_wiki(wiki_name):
250 exists = self.storage.has_item(item_name) 265 exists = bool(self.storage.get_item(**fqname.query))
251 wiki_name = '' # means "this wiki" for the theme code 266 wiki_name = '' # means "this wiki" for the theme code
252 else: 267 else:
253 exists = True # we can't detect existance of remote items 268 exists = True # we can't detect existance of remote items
254 breadcrumbs.append((wiki_name, item_name, href, exists, err)) 269 if item_name:
270 breadcrumbs.append((wiki_name, fqname, href, exists, err))
255 return breadcrumbs 271 return breadcrumbs
256 272
257 def subitem_index(self, item_name): 273 def subitem_index(self, fqname):
258 """ 274 """
259 Get a list of subitems for the given item_name 275 Get a list of subitems for the given fqname
260 276
261 :rtype: list 277 :rtype: list
262 :returns: list of item tuples (item_name, item_title, item_mime_type, has_children) 278 :returns: list of item tuples (item_name, item_title, item_mime_type, has_children)
263 """ 279 """
264 from MoinMoin.items import Item 280 from MoinMoin.items import Item
265 item = Item.create(item_name) 281 if not isinstance(fqname, CompositeName):
282 fqname = split_fqname(fqname)
283 item = Item.create(fqname.fullname)
266 return item.get_mixed_index() 284 return item.get_mixed_index()
267 285
268 def userhome(self): 286 def userhome(self):
269 """ 287 """
270 Assemble arguments used to build user homepage link 288 Assemble arguments used to build user homepage link
281 if is_local_wiki(wikiname): 299 if is_local_wiki(wikiname):
282 exists = self.storage.has_item(itemname) 300 exists = self.storage.has_item(itemname)
283 else: 301 else:
284 # We cannot check if wiki pages exists in remote wikis 302 # We cannot check if wiki pages exists in remote wikis
285 exists = True 303 exists = True
286 wiki_href = url_for_item(itemname, wiki_name=wikiname) 304 wiki_href = url_for_item(itemname, wiki_name=wikiname, namespace=NAMESPACE_USERPROFILES)
287 return wiki_href, display_name, title, exists 305 return wiki_href, display_name, title, exists
288 306
289 def split_navilink(self, text): 307 def split_navilink(self, text):
290 """ 308 """
291 Split navibar links into pagename, link to page 309 Split navibar links into pagename, link to page
327 345
328 # remove wiki: url prefix 346 # remove wiki: url prefix
329 if target.startswith("wiki:"): 347 if target.startswith("wiki:"):
330 target = target[5:] 348 target = target[5:]
331 349
332 wiki_name, namespace, item_name = split_interwiki(target) 350 wiki_name, namespace, field, item_name = split_interwiki(target)
333 if wiki_name == 'Self': 351 if wiki_name == 'Self':
334 wiki_name = '' 352 wiki_name = ''
335 href = url_for_item(item_name, namespace=namespace, wiki_name=wiki_name) 353 href = url_for_item(item_name, namespace=namespace, wiki_name=wiki_name, field=field)
336 if not title: 354 if not title:
337 title = item_name 355 title = shorten_fqname(CompositeName(namespace, field, item_name))
338 return href, title, wiki_name 356 return href, title, wiki_name
339 357
340 @timed() 358 @timed()
341 def navibar(self, item_name): 359 def navibar(self, fqname):
342 """ 360 """
343 Assemble the navibar 361 Assemble the navibar
344 362
345 :rtype: list 363 :rtype: list
346 :returns: list of tuples (css_class, url, link_text, title) 364 :returns: list of tuples (css_class, url, link_text, title)
347 """ 365 """
366 if not isinstance(fqname, CompositeName):
367 fqname = split_fqname(fqname)
368 item_name = fqname.value
348 current = item_name 369 current = item_name
349 # Process config navi_bar 370 # Process config navi_bar
350 items = [] 371 items = []
351 for cls, endpoint, args, link_text, title in self.cfg.navi_bar: 372 for cls, endpoint, args, link_text, title in self.cfg.navi_bar:
352 if endpoint == "frontend.show_root": 373 if endpoint == "frontend.show_root":
353 endpoint = "frontend.show_item" 374 endpoint = "frontend.show_item"
354 args['item_name'] = app.cfg.item_root 375 root_fqname = fqname.get_root_fqname()
376 default_root = app.cfg.root_mapping.get(NAMESPACE_DEFAULT, app.cfg.default_root)
377 args['item_name'] = root_fqname.fullname if fqname.namespace != NAMESPACE_ALL else default_root
378 elif endpoint in ["frontend.global_history", "frontend.global_tags"]:
379 args['namespace'] = fqname.namespace
380 elif endpoint == "frontend.index":
381 args['item_name'] = fqname.namespace
355 items.append((cls, url_for(endpoint, **args), link_text, title)) 382 items.append((cls, url_for(endpoint, **args), link_text, title))
356 383
357 # Add user links to wiki links. 384 # Add user links to wiki links.
358 for text in self.user.quicklinks: 385 for text in self.user.quicklinks:
359 url, link_text, title = self.split_navilink(text) 386 url, link_text, title = self.split_navilink(text)
418 url = url_for('frontend.login', login=1) 445 url = url_for('frontend.login', login=1)
419 if self.cfg.auth_have_login: 446 if self.cfg.auth_have_login:
420 url = url or url_for('frontend.login') 447 url = url or url_for('frontend.login')
421 return url 448 return url
422 449
450 def get_fqnames(self, fqname):
451 """
452 Return the list of other fqnames associated with the item.
453 """
454 if fqname.field != NAME_EXACT:
455 return []
456 item = self.storage.get_item(**fqname.query)
457 fqnames = item.fqnames
458 fqnames.remove(fqname)
459 return fqnames or []
460
461 def get_namespaces(self, ns):
462 """
463 Return the list of tuples (composite name, namespace) referring to namespaces other
464 than the current namespace.
465 """
466 ns = u'' if ns.value == '~' else ns.value
467 namespace_root_mapping = []
468 for namespace, _ in app.cfg.namespace_mapping:
469 namespace = namespace.rstrip('/')
470 if namespace != ns:
471 fq_namespace = CompositeName(namespace, NAME_EXACT, u'')
472 namespace_root_mapping.append((namespace or '~', fq_namespace.get_root_fqname()))
473 return namespace_root_mapping
474
423 475
424 def get_editor_info(meta, external=False): 476 def get_editor_info(meta, external=False):
425 addr = meta.get(ADDRESS) 477 addr = meta.get(ADDRESS)
426 hostname = meta.get(HOSTNAME) 478 hostname = meta.get(HOSTNAME)
427 text = _('anonymous') # link text 479 text = _('anonymous') # link text
469 if email: 521 if email:
470 result['email'] = email 522 result['email'] = email
471 return result 523 return result
472 524
473 525
526 def shorten_fqname(fqname, length=25):
527 """
528 Shorten fqname
529
530 Shorten a given long fqname so that it looks good depending upon whether
531 the field is a UUID or not.
532
533 :param fqname: fqname, namedtuple
534 :param length maximum length for shortened fqnames in case the field
535 is not a UUID.
536 :rtype: unicode
537 :returns: shortened fqname.
538 """
539 name = fqname.value
540 if len(name) > length:
541 if fqname.field in [REVID, ITEMID]:
542 name = shorten_id(name)
543 else:
544 name = shorten_item_name(name, length)
545 return name
546
547
474 def shorten_item_name(name, length=25): 548 def shorten_item_name(name, length=25):
475 """ 549 """
476 Shorten item names 550 Shorten item names
477 551
478 Shorten very long item names that tend to break the user 552 Shorten very long item names that tend to break the user
563 from calendar import timegm 637 from calendar import timegm
564 return timegm(dt.timetuple()) 638 return timegm(dt.timetuple())
565 639
566 640
567 def setup_jinja_env(): 641 def setup_jinja_env():
642 app.jinja_env.filters['shorten_fqname'] = shorten_fqname
568 app.jinja_env.filters['shorten_item_name'] = shorten_item_name 643 app.jinja_env.filters['shorten_item_name'] = shorten_item_name
569 app.jinja_env.filters['shorten_id'] = shorten_id 644 app.jinja_env.filters['shorten_id'] = shorten_id
570 app.jinja_env.filters['contenttype_to_class'] = contenttype_to_class 645 app.jinja_env.filters['contenttype_to_class'] = contenttype_to_class
571 app.jinja_env.filters['json_dumps'] = dumps 646 app.jinja_env.filters['json_dumps'] = dumps
572 app.jinja_env.filters['shorten_ctype'] = shorten_content_type 647 app.jinja_env.filters['shorten_ctype'] = shorten_content_type
584 'theme_supp': ThemeSupport(app.cfg), 659 'theme_supp': ThemeSupport(app.cfg),
585 'user': flaskg.user, 660 'user': flaskg.user,
586 'storage': flaskg.storage, 661 'storage': flaskg.storage,
587 'clock': flaskg.clock, 662 'clock': flaskg.clock,
588 'cfg': app.cfg, 663 'cfg': app.cfg,
589 'item_name': u'@NONAMEGIVEN', 664 'item_name': u'@NONAMEGIVEN', # XXX can we just use u'' ?
590 'url_for_item': url_for_item, 665 'url_for_item': url_for_item,
591 'get_editor_info': lambda meta: get_editor_info(meta), 666 'get_editor_info': lambda meta: get_editor_info(meta),
592 'utctimestamp': lambda dt: utctimestamp(dt), 667 'utctimestamp': lambda dt: utctimestamp(dt),
593 'gen': make_generator(), 668 'gen': make_generator(),
594 'search_form': SearchForm.from_defaults(), 669 'search_form': SearchForm.from_defaults(),