##// END OF EJS Templates
made global funcion to clean repo names, and remove all special chars from the name....
marcink -
r260:6ada8c22 default
parent child Browse files
Show More
@@ -1,91 +1,91 b''
1 import logging
1 import logging
2 import cgi
2 import cgi
3 import os
3 import os
4 import paste.fileapp
4 import paste.fileapp
5 from pylons import tmpl_context as c, app_globals as g, request, config
5 from pylons import tmpl_context as c, app_globals as g, request, config
6 from pylons.controllers.util import forward
6 from pylons.controllers.util import forward
7 from pylons.i18n.translation import _
7 from pylons.i18n.translation import _
8 from pylons_app.lib.base import BaseController, render
8 from pylons_app.lib.base import BaseController, render
9 from pylons.middleware import media_path
9 from pylons.middleware import media_path
10 from pylons_app.lib.utils import check_repo
10 from pylons_app.lib.utils import check_repo
11 from pylons_app.lib.filters import clean_repo
11 import pylons_app.lib.helpers as h
12 log = logging.getLogger(__name__)
12 log = logging.getLogger(__name__)
13
13
14 class ErrorController(BaseController):
14 class ErrorController(BaseController):
15 """
15 """
16 Generates error documents as and when they are required.
16 Generates error documents as and when they are required.
17
17
18 The ErrorDocuments middleware forwards to ErrorController when error
18 The ErrorDocuments middleware forwards to ErrorController when error
19 related status codes are returned from the application.
19 related status codes are returned from the application.
20
20
21 This behaviour can be altered by changing the parameters to the
21 This behaviour can be altered by changing the parameters to the
22 ErrorDocuments middleware in your config/middleware.py file.
22 ErrorDocuments middleware in your config/middleware.py file.
23 """
23 """
24 # def __before__(self):
24 # def __before__(self):
25 # super(ErrorController, self).__before__()
25 # super(ErrorController, self).__before__()
26
26
27 def document(self):
27 def document(self):
28 resp = request.environ.get('pylons.original_response')
28 resp = request.environ.get('pylons.original_response')
29
29
30 log.debug(resp.status)
30 log.debug(resp.status)
31
31
32 e = request.environ
32 e = request.environ
33 c.serv_p = r'%(protocol)s://%(host)s/' % {
33 c.serv_p = r'%(protocol)s://%(host)s/' % {
34 'protocol': e.get('wsgi.url_scheme'),
34 'protocol': e.get('wsgi.url_scheme'),
35 'host':e.get('HTTP_HOST'),
35 'host':e.get('HTTP_HOST'),
36 }
36 }
37
37
38
38
39 if resp.status_int == 404:
39 if resp.status_int == 404:
40 org_e = request.environ.get('pylons.original_request').environ
40 org_e = request.environ.get('pylons.original_request').environ
41 c.repo_name = repo_name = org_e['PATH_INFO'].split('/')[1]
41 c.repo_name = repo_name = org_e['PATH_INFO'].split('/')[1]
42 c.repo_name_cleaned = clean_repo(c.repo_name)
42 c.repo_name_cleaned = h.repo_name_slug(c.repo_name)
43 if check_repo(repo_name, g.base_path):
43 if check_repo(repo_name, g.base_path):
44 return render('/errors/error_404.html')
44 return render('/errors/error_404.html')
45
45
46 c.error_message = cgi.escape(request.GET.get('code', str(resp.status)))
46 c.error_message = cgi.escape(request.GET.get('code', str(resp.status)))
47 c.error_explanation = self.get_error_explanation(resp.status_int)
47 c.error_explanation = self.get_error_explanation(resp.status_int)
48
48
49 #redirect to when error with given seconds
49 #redirect to when error with given seconds
50 c.redirect_time = 0
50 c.redirect_time = 0
51 c.redirect_module = _('Home page')# name to what your going to be redirected
51 c.redirect_module = _('Home page')# name to what your going to be redirected
52 c.url_redirect = "/"
52 c.url_redirect = "/"
53
53
54 return render('/errors/error_document.html')
54 return render('/errors/error_document.html')
55
55
56
56
57 def img(self, id):
57 def img(self, id):
58 """Serve Pylons' stock images"""
58 """Serve Pylons' stock images"""
59 return self._serve_file(os.path.join(media_path, 'img', id))
59 return self._serve_file(os.path.join(media_path, 'img', id))
60
60
61 def style(self, id):
61 def style(self, id):
62 """Serve Pylons' stock stylesheets"""
62 """Serve Pylons' stock stylesheets"""
63 return self._serve_file(os.path.join(media_path, 'style', id))
63 return self._serve_file(os.path.join(media_path, 'style', id))
64
64
65 def _serve_file(self, path):
65 def _serve_file(self, path):
66 """Call Paste's FileApp (a WSGI application) to serve the file
66 """Call Paste's FileApp (a WSGI application) to serve the file
67 at the specified path
67 at the specified path
68 """
68 """
69 fapp = paste.fileapp.FileApp(path)
69 fapp = paste.fileapp.FileApp(path)
70 return fapp(request.environ, self.start_response)
70 return fapp(request.environ, self.start_response)
71
71
72 def get_error_explanation(self, code):
72 def get_error_explanation(self, code):
73 ''' get the error explanations of int codes
73 ''' get the error explanations of int codes
74 [400, 401, 403, 404, 500]'''
74 [400, 401, 403, 404, 500]'''
75 try:
75 try:
76 code = int(code)
76 code = int(code)
77 except:
77 except:
78 code = 500
78 code = 500
79
79
80 if code == 400:
80 if code == 400:
81 return _('The request could not be understood by the server due to malformed syntax.')
81 return _('The request could not be understood by the server due to malformed syntax.')
82 if code == 401:
82 if code == 401:
83 return _('Unathorized access to resource')
83 return _('Unathorized access to resource')
84 if code == 403:
84 if code == 403:
85 return _("You don't have permission to view this page")
85 return _("You don't have permission to view this page")
86 if code == 404:
86 if code == 404:
87 return _('The resource could not be found')
87 return _('The resource could not be found')
88 if code == 500:
88 if code == 500:
89 return _('The server encountered an unexpected condition which prevented it from fulfilling the request.')
89 return _('The server encountered an unexpected condition which prevented it from fulfilling the request.')
90
90
91
91
@@ -1,49 +1,41 b''
1 #!/usr/bin/env python
1 #!/usr/bin/env python
2 # encoding: utf-8
2 # encoding: utf-8
3 # simple filters for hg apps html templates
3 # simple filters for hg apps html templates
4 # Copyright (C) 2009-2010 Marcin Kuzminski <marcin@python-works.com>
4 # Copyright (C) 2009-2010 Marcin Kuzminski <marcin@python-works.com>
5
5
6 # This program is free software; you can redistribute it and/or
6 # This program is free software; you can redistribute it and/or
7 # modify it under the terms of the GNU General Public License
7 # modify it under the terms of the GNU General Public License
8 # as published by the Free Software Foundation; version 2
8 # as published by the Free Software Foundation; version 2
9 # of the License or (at your opinion) any later version of the license.
9 # of the License or (at your opinion) any later version of the license.
10 #
10 #
11 # This program is distributed in the hope that it will be useful,
11 # This program is distributed in the hope that it will be useful,
12 # but WITHOUT ANY WARRANTY; without even the implied warranty of
12 # but WITHOUT ANY WARRANTY; without even the implied warranty of
13 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 # GNU General Public License for more details.
14 # GNU General Public License for more details.
15 #
15 #
16 # You should have received a copy of the GNU General Public License
16 # You should have received a copy of the GNU General Public License
17 # along with this program; if not, write to the Free Software
17 # along with this program; if not, write to the Free Software
18 # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
18 # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
19 # MA 02110-1301, USA.
19 # MA 02110-1301, USA.
20
20
21 """
21 """
22 Created on April 12, 2010
22 Created on April 12, 2010
23 simple filters for hg apps html templates
23 simple filters for hg apps html templates
24 @author: marcink
24 @author: marcink
25 """
25 """
26
26
27 from mercurial import util
27 from mercurial import util
28 from mercurial.templatefilters import age as _age, person as _person
28 from mercurial.templatefilters import age as _age, person as _person
29 from string import punctuation
30
31 def clean_repo(repo_name):
32 for x in punctuation:
33 if x != '_':
34 repo_name = repo_name.replace(x, '')
35 repo_name = repo_name.lower().strip()
36 return repo_name.replace(' ', '_')
37
29
38 age = lambda x:_age(x)
30 age = lambda x:_age(x)
39 capitalize = lambda x: x.capitalize()
31 capitalize = lambda x: x.capitalize()
40 date = lambda x: util.datestr(x)
32 date = lambda x: util.datestr(x)
41 email = util.email
33 email = util.email
42 person = lambda x: _person(x)
34 person = lambda x: _person(x)
43 hgdate = lambda x: "%d %d" % x
35 hgdate = lambda x: "%d %d" % x
44 isodate = lambda x: util.datestr(x, '%Y-%m-%d %H:%M %1%2')
36 isodate = lambda x: util.datestr(x, '%Y-%m-%d %H:%M %1%2')
45 isodatesec = lambda x: util.datestr(x, '%Y-%m-%d %H:%M:%S %1%2')
37 isodatesec = lambda x: util.datestr(x, '%Y-%m-%d %H:%M:%S %1%2')
46 localdate = lambda x: (x[0], util.makedate()[1])
38 localdate = lambda x: (x[0], util.makedate()[1])
47 rfc822date = lambda x: util.datestr(x, "%a, %d %b %Y %H:%M:%S %1%2")
39 rfc822date = lambda x: util.datestr(x, "%a, %d %b %Y %H:%M:%S %1%2")
48 rfc3339date = lambda x: util.datestr(x, "%Y-%m-%dT%H:%M:%S%1:%2")
40 rfc3339date = lambda x: util.datestr(x, "%Y-%m-%dT%H:%M:%S%1:%2")
49 time_ago = lambda x: util.datestr(_age(x), "%a, %d %b %Y %H:%M:%S %1%2")
41 time_ago = lambda x: util.datestr(_age(x), "%a, %d %b %Y %H:%M:%S %1%2")
@@ -1,98 +1,127 b''
1 """Helper functions
1 """Helper functions
2
2
3 Consists of functions to typically be used within templates, but also
3 Consists of functions to typically be used within templates, but also
4 available to Controllers. This module is available to both as 'h'.
4 available to Controllers. This module is available to both as 'h'.
5 """
5 """
6 from pygments.formatters import HtmlFormatter
6 from pygments.formatters import HtmlFormatter
7 from pygments import highlight as code_highlight
7 from pygments import highlight as code_highlight
8 from pylons import url, app_globals as g
8 from pylons import url, app_globals as g
9 from pylons.i18n.translation import _, ungettext
9 from pylons.i18n.translation import _, ungettext
10 from vcs.utils.annotate import annotate_highlight
10 from vcs.utils.annotate import annotate_highlight
11 from webhelpers.html import literal, HTML, escape
11 from webhelpers.html import literal, HTML, escape
12 from webhelpers.html.builder import make_tag
12 from webhelpers.html.builder import make_tag
13 from webhelpers.html.tags import auto_discovery_link, checkbox, css_classes, \
13 from webhelpers.html.tags import auto_discovery_link, checkbox, css_classes, \
14 end_form, file, form, hidden, image, javascript_link, link_to, link_to_if, \
14 end_form, file, form, hidden, image, javascript_link, link_to, link_to_if, \
15 link_to_unless, ol, required_legend, select, stylesheet_link, submit, text, \
15 link_to_unless, ol, required_legend, select, stylesheet_link, submit, text, \
16 password, textarea, title, ul, xml_declaration
16 password, textarea, title, ul, xml_declaration
17 from webhelpers.html.tools import auto_link, button_to, highlight, js_obfuscate, \
17 from webhelpers.html.tools import auto_link, button_to, highlight, js_obfuscate, \
18 mail_to, strip_links, strip_tags, tag_re
18 mail_to, strip_links, strip_tags, tag_re
19 from webhelpers.number import format_byte_size, format_bit_size
19 from webhelpers.number import format_byte_size, format_bit_size
20 from webhelpers.pylonslib import Flash as _Flash
20 from webhelpers.pylonslib import Flash as _Flash
21 from webhelpers.pylonslib.secure_form import secure_form
21 from webhelpers.pylonslib.secure_form import secure_form
22 from webhelpers.text import chop_at, collapse, convert_accented_entities, \
22 from webhelpers.text import chop_at, collapse, convert_accented_entities, \
23 convert_misc_entities, lchop, plural, rchop, remove_formatting, \
23 convert_misc_entities, lchop, plural, rchop, remove_formatting, \
24 replace_whitespace, urlify
24 replace_whitespace, urlify, truncate
25
25
26
26
27 #Custom helper here :)
27 #Custom helper here :)
28 class _Link(object):
28 class _Link(object):
29 '''
29 '''
30 Make a url based on label and url with help of url_for
30 Make a url based on label and url with help of url_for
31 @param label:name of link if not defined url is used
31 @param label:name of link if not defined url is used
32 @param url: the url for link
32 @param url: the url for link
33 '''
33 '''
34
34
35 def __call__(self, label='', *url_, **urlargs):
35 def __call__(self, label='', *url_, **urlargs):
36 if label is None or '':
36 if label is None or '':
37 label = url
37 label = url
38 link_fn = link_to(label, url(*url_, **urlargs))
38 link_fn = link_to(label, url(*url_, **urlargs))
39 return link_fn
39 return link_fn
40
40
41
41
42 class _GetError(object):
42 class _GetError(object):
43
43
44 def __call__(self, field_name, form_errors):
44 def __call__(self, field_name, form_errors):
45 tmpl = """<span class="error_msg">%s</span>"""
45 tmpl = """<span class="error_msg">%s</span>"""
46 if form_errors and form_errors.has_key(field_name):
46 if form_errors and form_errors.has_key(field_name):
47 return literal(tmpl % form_errors.get(field_name))
47 return literal(tmpl % form_errors.get(field_name))
48
48
49 class _FilesBreadCrumbs(object):
49 class _FilesBreadCrumbs(object):
50
50
51 def __call__(self, repo_name, rev, paths):
51 def __call__(self, repo_name, rev, paths):
52 url_l = [link_to(repo_name, url('files_home', repo_name=repo_name, revision=rev, f_path=''))]
52 url_l = [link_to(repo_name, url('files_home', repo_name=repo_name, revision=rev, f_path=''))]
53 paths_l = paths.split('/')
53 paths_l = paths.split('/')
54
54
55 for cnt, p in enumerate(paths_l, 1):
55 for cnt, p in enumerate(paths_l, 1):
56 if p != '':
56 if p != '':
57 url_l.append(link_to(p, url('files_home', repo_name=repo_name, revision=rev, f_path='/'.join(paths_l[:cnt]))))
57 url_l.append(link_to(p, url('files_home', repo_name=repo_name, revision=rev, f_path='/'.join(paths_l[:cnt]))))
58
58
59 return literal(' / '.join(url_l))
59 return literal(' / '.join(url_l))
60
60
61 def pygmentize(filenode, **kwargs):
61 def pygmentize(filenode, **kwargs):
62 """
62 """
63 pygmentize function using pygments
63 pygmentize function using pygments
64 @param filenode:
64 @param filenode:
65 """
65 """
66 return literal(code_highlight(filenode.content, filenode.lexer, HtmlFormatter(**kwargs)))
66 return literal(code_highlight(filenode.content, filenode.lexer, HtmlFormatter(**kwargs)))
67
67
68 def pygmentize_annotation(filenode, **kwargs):
68 def pygmentize_annotation(filenode, **kwargs):
69 """
69 """
70 pygmentize function for annotation
70 pygmentize function for annotation
71 @param filenode:
71 @param filenode:
72 """
72 """
73
73
74 color_dict = g.changeset_annotation_colors
74 color_dict = g.changeset_annotation_colors
75 def gen_color():
75 def gen_color():
76 import random
76 import random
77 return [str(random.randrange(10, 235)) for _ in xrange(3)]
77 return [str(random.randrange(10, 235)) for _ in xrange(3)]
78 def get_color_string(cs):
78 def get_color_string(cs):
79 if color_dict.has_key(cs):
79 if color_dict.has_key(cs):
80 col = color_dict[cs]
80 col = color_dict[cs]
81 else:
81 else:
82 color_dict[cs] = gen_color()
82 color_dict[cs] = gen_color()
83 col = color_dict[cs]
83 col = color_dict[cs]
84 return "color: rgb(%s) ! important;" % (','.join(col))
84 return "color: rgb(%s) ! important;" % (','.join(col))
85
85
86 def url_func(changeset):
86 def url_func(changeset):
87 return '%s\n' % (link_to(changeset.raw_id,
87 return '%s\n' % (link_to(changeset.raw_id,
88 url('changeset_home', repo_name='test', revision=changeset.raw_id),
88 url('changeset_home', repo_name='test', revision=changeset.raw_id),
89 title=_('author') + ':%s rev:%s %s' % (changeset.author, changeset.revision,
89 title=_('author') + ':%s rev:%s %s' % (changeset.author, changeset.revision,
90 changeset.message,),
90 changeset.message,),
91 style=get_color_string(changeset.raw_id)))
91 style=get_color_string(changeset.raw_id)))
92
92
93 return literal(annotate_highlight(filenode, url_func, **kwargs))
93 return literal(annotate_highlight(filenode, url_func, **kwargs))
94
94
95 def recursive_replace(str, replace=' '):
96 """
97 Recursive replace of given sign to just one instance
98 @param str: given string
99 @param replace:char to find and replace multiple instances
100
101 Examples::
102 >>> recursive_replace("Mighty---Mighty-Bo--sstones",'-')
103 'Mighty-Mighty-Bo-sstones'
104 """
105
106 if str.find(replace * 2) == -1:
107 return str
108 else:
109 str = str.replace(replace * 2, replace)
110 return recursive_replace(str, replace)
111
112 def repo_name_slug(value):
113 """
114 Return slug of name of repository
115 """
116 slug = urlify(value)
117 for c in """=[]\;',/~!@#$%^&*()+{}|:""":
118 slug = slug.replace(c, '-')
119 print slug
120 slug = recursive_replace(slug, '-')
121 print slug
122 return slug
123
95 files_breadcrumbs = _FilesBreadCrumbs()
124 files_breadcrumbs = _FilesBreadCrumbs()
96 link = _Link()
125 link = _Link()
97 flash = _Flash()
126 flash = _Flash()
98 get_error = _GetError()
127 get_error = _GetError()
@@ -1,165 +1,154 b''
1 ## -*- coding: utf-8 -*-
1 ## -*- coding: utf-8 -*-
2 <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
2 <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
3 <html xmlns="http://www.w3.org/1999/xhtml" id="mainhtml">
3 <html xmlns="http://www.w3.org/1999/xhtml" id="mainhtml">
4 <head>
4 <head>
5 <link rel="icon" href="/images/hgicon.png" type="image/png" />
5 <link rel="icon" href="/images/hgicon.png" type="image/png" />
6 <meta name="robots" content="index, nofollow"/>
6 <meta name="robots" content="index, nofollow"/>
7 <title>${next.title()}</title>
7 <title>${next.title()}</title>
8 ##For future use yui reset for cross browser compatability.
8 ##For future use yui reset for cross browser compatability.
9 ##<link rel="stylesheet" href="/js/yui/reset-fonts-grids/reset-fonts-grids.css" type="text/css" />
9 ##<link rel="stylesheet" href="/js/yui/reset-fonts-grids/reset-fonts-grids.css" type="text/css" />
10 ${self.css()}
10 ${self.css()}
11 ${self.js()}
11 ${self.js()}
12 </head>
12 </head>
13
13
14 <body class="mainbody">
14 <body class="mainbody">
15 <div id="container">
15 <div id="container">
16 <div class="page-header">
16 <div class="page-header">
17 <h1>${next.breadcrumbs()}</h1>
17 <h1>${next.breadcrumbs()}</h1>
18 ${self.page_nav()}
18 ${self.page_nav()}
19 <div class="flash_msg">
19 <div class="flash_msg">
20 <% messages = h.flash.pop_messages() %>
20 <% messages = h.flash.pop_messages() %>
21 % if messages:
21 % if messages:
22 <ul id="flash-messages">
22 <ul id="flash-messages">
23 % for message in messages:
23 % for message in messages:
24 <li class="${message.category}_msg">${message}</li>
24 <li class="${message.category}_msg">${message}</li>
25 % endfor
25 % endfor
26 </ul>
26 </ul>
27 % endif
27 % endif
28 </div>
28 </div>
29 <div id="main">
29 <div id="main">
30 ${next.main()}
30 ${next.main()}
31 </div>
31 </div>
32 <div class="page-footer">
32 <div class="page-footer">
33 Hg App ${c.hg_app_version} &copy; 2010 by Marcin Kuzminski
33 Hg App ${c.hg_app_version} &copy; 2010 by Marcin Kuzminski
34 </div>
34 </div>
35
35
36 <div id="powered-by">
36 <div id="powered-by">
37 <p>
37 <p>
38 <a href="http://mercurial.selenic.com/" title="Mercurial">
38 <a href="http://mercurial.selenic.com/" title="Mercurial">
39 <img src="/images/hglogo.png" width="75" height="90" alt="mercurial"/></a>
39 <img src="/images/hglogo.png" width="75" height="90" alt="mercurial"/></a>
40 </p>
40 </p>
41 </div>
41 </div>
42
42
43 <div id="corner-top-left"></div>
43 <div id="corner-top-left"></div>
44 <div id="corner-top-right"></div>
44 <div id="corner-top-right"></div>
45 <div id="corner-bottom-left"></div>
45 <div id="corner-bottom-left"></div>
46 <div id="corner-bottom-right"></div>
46 <div id="corner-bottom-right"></div>
47
47
48 </div>
48 </div>
49 </body>
49 </body>
50 </html>
50 </html>
51
51
52 ### MAKO DEFS ###
52 ### MAKO DEFS ###
53
53
54 <%def name="page_nav()">
54 <%def name="page_nav()">
55 ${self.menu()}
55 ${self.menu()}
56 ${self.submenu()}
56 ${self.submenu()}
57 </%def>
57 </%def>
58
58
59 <%def name="menu(current)">
59 <%def name="menu(current)">
60 <%
60 <%
61 def is_current(selected):
61 def is_current(selected):
62 if selected == current:
62 if selected == current:
63 return "class='current'"
63 return "class='current'"
64 %>
64 %>
65 %if current not in ['home','admin']:
65 %if current not in ['home','admin']:
66 ##regular menu
66 ##regular menu
67 <script type="text/javascript">
67 <script type="text/javascript">
68 YAHOO.util.Event.onDOMReady(function(){
68 YAHOO.util.Event.onDOMReady(function(){
69 YAHOO.util.Event.addListener('repo_switcher','click',function(){
69 YAHOO.util.Event.addListener('repo_switcher','click',function(){
70 if(YAHOO.util.Dom.hasClass('repo_switcher','selected')){
70 if(YAHOO.util.Dom.hasClass('repo_switcher','selected')){
71 YAHOO.util.Dom.setStyle('switch_repos','display','none');
71 YAHOO.util.Dom.setStyle('switch_repos','display','none');
72 YAHOO.util.Dom.setStyle('repo_switcher','background','');
72 YAHOO.util.Dom.setStyle('repo_switcher','background','');
73 YAHOO.util.Dom.removeClass('repo_switcher','selected');
73 YAHOO.util.Dom.removeClass('repo_switcher','selected');
74 YAHOO.util.Dom.get('repo_switcher').removeAttribute('style');
74 YAHOO.util.Dom.get('repo_switcher').removeAttribute('style');
75 }
75 }
76 else{
76 else{
77 YAHOO.util.Dom.setStyle('switch_repos','display','');
77 YAHOO.util.Dom.setStyle('switch_repos','display','');
78 YAHOO.util.Dom.setStyle('repo_switcher','background','#FFFFFF');
78 YAHOO.util.Dom.setStyle('repo_switcher','background','#FFFFFF');
79 YAHOO.util.Dom.setStyle('repo_switcher','color','#556CB5');
79 YAHOO.util.Dom.setStyle('repo_switcher','color','#556CB5');
80 YAHOO.util.Dom.addClass('repo_switcher','selected');
80 YAHOO.util.Dom.addClass('repo_switcher','selected');
81 }
81 }
82 });
82 });
83 YAHOO.util.Event.addListener('repos_list','change',function(e){
83 YAHOO.util.Event.addListener('repos_list','change',function(e){
84 var wa = YAHOO.util.Dom.get('repos_list').value;
84 var wa = YAHOO.util.Dom.get('repos_list').value;
85
85
86 var url = "${h.url('summary_home',repo_name='__REPLACE__')}".replace('__REPLACE__',wa);
86 var url = "${h.url('summary_home',repo_name='__REPLACE__')}".replace('__REPLACE__',wa);
87 window.location = url;
87 window.location = url;
88 })
88 })
89 });
89 });
90 </script>
90 </script>
91 <ul class="page-nav">
91 <ul class="page-nav">
92 <li>
92 <li>
93 <a id="repo_switcher" title="${_('Switch repository')}" href="#">&darr;</a>
93 <a id="repo_switcher" title="${_('Switch repository')}" href="#">&darr;</a>
94 <div id="switch_repos" style="display:none;position: absolute;width: 150px;height: 25px">
94 <div id="switch_repos" style="display:none;position: absolute;width: 150px;height: 25px">
95 <select id="repos_list" size="=10">
95 <select id="repos_list" size="=10">
96 %for repo in sorted(x.name.lower() for x in c.cached_repo_list.values()):
96 %for repo in sorted(x.name.lower() for x in c.cached_repo_list.values()):
97 <option value="${repo}">${repo}</option>
97 <option value="${repo}">${repo}</option>
98 %endfor
98 %endfor
99 </select>
99 </select>
100 </div>
100 </div>
101 </li>
101 </li>
102 <li ${is_current('summary')}>${h.link_to(_('summary'),h.url('summary_home',repo_name=c.repo_name))}</li>
102 <li ${is_current('summary')}>${h.link_to(_('summary'),h.url('summary_home',repo_name=c.repo_name))}</li>
103 <li ${is_current('shortlog')}>${h.link_to(_('shortlog'),h.url('shortlog_home',repo_name=c.repo_name))}</li>
103 <li ${is_current('shortlog')}>${h.link_to(_('shortlog'),h.url('shortlog_home',repo_name=c.repo_name))}</li>
104 <li ${is_current('changelog')}>${h.link_to(_('changelog'),h.url('changelog_home',repo_name=c.repo_name))}</li>
104 <li ${is_current('changelog')}>${h.link_to(_('changelog'),h.url('changelog_home',repo_name=c.repo_name))}</li>
105 <li ${is_current('branches')}>${h.link_to(_('branches'),h.url('branches_home',repo_name=c.repo_name))}</li>
105 <li ${is_current('branches')}>${h.link_to(_('branches'),h.url('branches_home',repo_name=c.repo_name))}</li>
106 <li ${is_current('tags')}>${h.link_to(_('tags'),h.url('tags_home',repo_name=c.repo_name))}</li>
106 <li ${is_current('tags')}>${h.link_to(_('tags'),h.url('tags_home',repo_name=c.repo_name))}</li>
107 <li ${is_current('files')}>${h.link_to(_('files'),h.url('files_home',repo_name=c.repo_name))}</li>
107 <li ${is_current('files')}>${h.link_to(_('files'),h.url('files_home',repo_name=c.repo_name))}</li>
108 </ul>
108 </ul>
109 %else:
109 %else:
110 ##Root menu
110 ##Root menu
111 <ul class="page-nav">
111 <ul class="page-nav">
112 <li ${is_current('home')}>${h.link_to(_('Home'),h.url('/'))}</li>
112 <li ${is_current('home')}>${h.link_to(_('Home'),h.url('/'))}</li>
113 <li ${is_current('admin')}>${h.link_to(_('Admin'),h.url('admin_home'))}</li>
113 <li ${is_current('admin')}>${h.link_to(_('Admin'),h.url('admin_home'))}</li>
114 <li class="logout">${h.link_to(u'Logout',h.url('logout_home'))}</li>
114 <li class="logout">${h.link_to(u'Logout',h.url('logout_home'))}</li>
115 </ul>
115 </ul>
116 %endif
116 %endif
117 </div>
117 </div>
118 </%def>
118 </%def>
119 <%def name="submenu(current=None)">
119 <%def name="submenu(current=None)">
120 <%
120 <%
121 def is_current(selected):
121 def is_current(selected):
122 if selected == current:
122 if selected == current:
123 return "class='current_submenu'"
123 return "class='current_submenu'"
124 %>
124 %>
125 %if current != None:
125 %if current != None:
126 <div>
126 <div>
127 <ul class="submenu">
127 <ul class="submenu">
128 <li ${is_current('repos')}>${h.link_to(u'repos',h.url('repos'),class_='repos')}</li>
128 <li ${is_current('repos')}>${h.link_to(u'repos',h.url('repos'),class_='repos')}</li>
129 <li ${is_current('users')}>${h.link_to(u'users',h.url('users'),class_='users')}</li>
129 <li ${is_current('users')}>${h.link_to(u'users',h.url('users'),class_='users')}</li>
130 <li ${is_current('permissions')}>${h.link_to(u'permissions',h.url('permissions'),class_='permissions')}</li>
130 <li ${is_current('permissions')}>${h.link_to(u'permissions',h.url('permissions'),class_='permissions')}</li>
131 </ul>
131 </ul>
132 </div>
132 </div>
133 %endif
133 %endif
134 </%def>
134 </%def>
135
135
136
136
137 <%def name="css()">
137 <%def name="css()">
138 <link rel="stylesheet" href="/css/monoblue_custom.css" type="text/css" />
138 <link rel="stylesheet" href="/css/monoblue_custom.css" type="text/css" />
139 </%def>
139 </%def>
140
140
141 <%def name="js()">
141 <%def name="js()">
142 <script type="text/javascript" src="/js/yui/utilities/utilities.js"></script>
142 <script type="text/javascript" src="/js/yui/utilities/utilities.js"></script>
143 </%def>
143 </%def>
144
144
145 <!-- DEFINITION OF FORM ERROR FETCHER -->
145 <!-- DEFINITION OF FORM ERROR FETCHER -->
146 <%def name="get_form_error(element)">
146 <%def name="get_form_error(element)">
147 %if hasattr(c,'form_errors') and type(c.form_errors) == dict:
147 %if hasattr(c,'form_errors') and type(c.form_errors) == dict:
148 %if c.form_errors.get(element,False):
148 %if c.form_errors.get(element,False):
149 <span class="error-message">
149 <span class="error-message">
150 ${c.form_errors.get(element,'')}
150 ${c.form_errors.get(element,'')}
151 </span>
151 </span>
152 %endif
152 %endif
153 %endif
153 %endif
154 </%def>
155
156 <!-- SHORTER LONGER STRINGS -->
157 <%def name="message_slug(msg)">
158 <%
159 limit = 60
160 if len(msg) > limit:
161 return msg[:limit]+'...'
162 else:
163 return msg
164 %>
165 </%def> No newline at end of file
154 </%def>
@@ -1,62 +1,62 b''
1 ## -*- coding: utf-8 -*-
1 ## -*- coding: utf-8 -*-
2 <%!
2 <%!
3 from pylons_app.lib import filters
3 from pylons_app.lib import filters
4 %>
4 %>
5 <%inherit file="base/base.html"/>
5 <%inherit file="base/base.html"/>
6 <%def name="title()">
6 <%def name="title()">
7 ${c.repos_prefix} Mercurial Repositories
7 ${c.repos_prefix} Mercurial Repositories
8 </%def>
8 </%def>
9 <%def name="breadcrumbs()">
9 <%def name="breadcrumbs()">
10 ${c.repos_prefix} Mercurial Repositories
10 ${c.repos_prefix} Mercurial Repositories
11 </%def>
11 </%def>
12 <%def name="page_nav()">
12 <%def name="page_nav()">
13 ${self.menu('home')}
13 ${self.menu('home')}
14 </%def>
14 </%def>
15 <%def name="main()">
15 <%def name="main()">
16 <%def name="get_sort(name)">
16 <%def name="get_sort(name)">
17 <%name_slug = name.lower().replace(' ','_') %>
17 <%name_slug = name.lower().replace(' ','_') %>
18 %if name_slug == c.cs_slug:
18 %if name_slug == c.cs_slug:
19 <span style="font-weight: bold;color:#006699">${name}</span>
19 <span style="font-weight: bold;color:#006699">${name}</span>
20 %else:
20 %else:
21 <span style="font-weight: bold">${name}</span>
21 <span style="font-weight: bold">${name}</span>
22 %endif
22 %endif
23 <a href="?sort=${name_slug}">&darr;</a>
23 <a href="?sort=${name_slug}">&darr;</a>
24 <a href="?sort=-${name_slug}">&uarr;</a>
24 <a href="?sort=-${name_slug}">&uarr;</a>
25 </%def>
25 </%def>
26 <table>
26 <table>
27 <tr>
27 <tr>
28 <td>${get_sort(_('Name'))}</td>
28 <td>${get_sort(_('Name'))}</td>
29 <td>${get_sort(_('Description'))}</td>
29 <td>${get_sort(_('Description'))}</td>
30 <td>${get_sort(_('Last change'))}</td>
30 <td>${get_sort(_('Last change'))}</td>
31 <td>${get_sort(_('Tip'))}</td>
31 <td>${get_sort(_('Tip'))}</td>
32 <td>${get_sort(_('Contact'))}</td>
32 <td>${get_sort(_('Contact'))}</td>
33 <td></td>
33 <td></td>
34 <td></td>
34 <td></td>
35 <td></td>
35 <td></td>
36 </tr>
36 </tr>
37 %for cnt,repo in enumerate(c.repos_list):
37 %for cnt,repo in enumerate(c.repos_list):
38 <tr class="parity${cnt%2}">
38 <tr class="parity${cnt%2}">
39 <td>${h.link(repo['name'],h.url('summary_home',repo_name=repo['name']))}</td>
39 <td>${h.link(repo['name'],h.url('summary_home',repo_name=repo['name']))}</td>
40 <td title="${repo['description']}">${self.message_slug(repo['description'])}</td>
40 <td title="${repo['description']}">${h.truncate(repo['description'],60)}</td>
41 <td>${repo['last_change']|n,filters.age}</td>
41 <td>${repo['last_change']|n,filters.age}</td>
42 <td>${h.link_to('r%s:%s' % (repo['rev'],repo['tip']),h.url('changeset_home',repo_name=repo['name'],revision=repo['tip']))}</td>
42 <td>${h.link_to('r%s:%s' % (repo['rev'],repo['tip']),h.url('changeset_home',repo_name=repo['name'],revision=repo['tip']))}</td>
43 <td title="${repo['contact']}">${repo['contact']|n,filters.person}</td>
43 <td title="${repo['contact']}">${repo['contact']|n,filters.person}</td>
44
44
45 ##%for archive in repo['repo_archives']:
45 ##%for archive in repo['repo_archives']:
46 ##<td class="indexlinks">
46 ##<td class="indexlinks">
47 ## ${h.link_to(archive['type'],
47 ## ${h.link_to(archive['type'],
48 ## h.url('files_archive_home',repo_name=repo['name'],
48 ## h.url('files_archive_home',repo_name=repo['name'],
49 ## revision='tip',fileformat=archive['extension']),class_="archive_logo" )}
49 ## revision='tip',fileformat=archive['extension']),class_="archive_logo" )}
50 ##</td>
50 ##</td>
51 ##%endfor
51 ##%endfor
52
52
53 <td>
53 <td>
54 ${h.link_to(_('RSS'),h.url('rss_feed_home',repo_name=repo['name']),class_='rss_logo')}
54 ${h.link_to(_('RSS'),h.url('rss_feed_home',repo_name=repo['name']),class_='rss_logo')}
55 </td>
55 </td>
56 <td>
56 <td>
57 ${h.link_to(_('Atom'),h.url('atom_feed_home',repo_name=repo['name']),class_='atom_logo')}
57 ${h.link_to(_('Atom'),h.url('atom_feed_home',repo_name=repo['name']),class_='atom_logo')}
58 </td>
58 </td>
59 </tr>
59 </tr>
60 %endfor
60 %endfor
61 </table>
61 </table>
62 </%def>
62 </%def>
@@ -1,48 +1,48 b''
1 ## -*- coding: utf-8 -*-
1 ## -*- coding: utf-8 -*-
2 <%!
2 <%!
3 from pylons_app.lib import filters
3 from pylons_app.lib import filters
4 %>
4 %>
5 <table>
5 <table>
6 %for cnt,cs in enumerate(c.repo_changesets):
6 %for cnt,cs in enumerate(c.repo_changesets):
7 <tr class="parity${cnt%2}">
7 <tr class="parity${cnt%2}">
8 <td>${cs._ctx.date()|n,filters.age}</td>
8 <td>${cs._ctx.date()|n,filters.age}</td>
9 <td title="${cs.author}">${cs.author|n,filters.person}</td>
9 <td title="${cs.author}">${cs.author|n,filters.person}</td>
10 <td>r${cs.revision}</td>
10 <td>r${cs.revision}</td>
11 <td>
11 <td>
12 ${h.link_to(self.message_slug(cs.message),
12 ${h.link_to(h.truncate(cs.message,60),
13 h.url('changeset_home',repo_name=c.repo_name,revision=cs._short),
13 h.url('changeset_home',repo_name=c.repo_name,revision=cs._short),
14 title=cs.message)}
14 title=cs.message)}
15 </td>
15 </td>
16 <td>
16 <td>
17 <span class="logtags">
17 <span class="logtags">
18 <span class="branchtag">${cs.branch}</span>
18 <span class="branchtag">${cs.branch}</span>
19 %for tag in cs.tags:
19 %for tag in cs.tags:
20 <span class="tagtag">${tag}</span>
20 <span class="tagtag">${tag}</span>
21 %endfor
21 %endfor
22 </span>
22 </span>
23 </td>
23 </td>
24 <td class="nowrap">
24 <td class="nowrap">
25 ${h.link_to(_('changeset'),h.url('changeset_home',repo_name=c.repo_name,revision=cs._short))}
25 ${h.link_to(_('changeset'),h.url('changeset_home',repo_name=c.repo_name,revision=cs._short))}
26 |
26 |
27 ${h.link_to(_('files'),h.url('files_home',repo_name=c.repo_name,revision=cs._short))}
27 ${h.link_to(_('files'),h.url('files_home',repo_name=c.repo_name,revision=cs._short))}
28 </td>
28 </td>
29 </tr>
29 </tr>
30 %endfor
30 %endfor
31
31
32 </table>
32 </table>
33 <div>
33 <div>
34 <script type="text/javascript">
34 <script type="text/javascript">
35 var data_div = 'shortlog_data';
35 var data_div = 'shortlog_data';
36 YAHOO.util.Event.onDOMReady(function(){
36 YAHOO.util.Event.onDOMReady(function(){
37 YAHOO.util.Event.addListener(YAHOO.util.Dom.getElementsByClassName('pager_link'),"click",function(){
37 YAHOO.util.Event.addListener(YAHOO.util.Dom.getElementsByClassName('pager_link'),"click",function(){
38 YAHOO.util.Dom.setStyle('shortlog_data','opacity','0.3');});});
38 YAHOO.util.Dom.setStyle('shortlog_data','opacity','0.3');});});
39 </script>
39 </script>
40 <h2>
40 <h2>
41 ${c.repo_changesets.pager('$link_previous ~2~ $link_next',
41 ${c.repo_changesets.pager('$link_previous ~2~ $link_next',
42 onclick="""YAHOO.util.Connect.asyncRequest('GET','$partial_url',{
42 onclick="""YAHOO.util.Connect.asyncRequest('GET','$partial_url',{
43 success:function(o){YAHOO.util.Dom.get(data_div).innerHTML=o.responseText;
43 success:function(o){YAHOO.util.Dom.get(data_div).innerHTML=o.responseText;
44 YAHOO.util.Event.addListener(YAHOO.util.Dom.getElementsByClassName('pager_link'),"click",function(){
44 YAHOO.util.Event.addListener(YAHOO.util.Dom.getElementsByClassName('pager_link'),"click",function(){
45 YAHOO.util.Dom.setStyle(data_div,'opacity','0.3');});
45 YAHOO.util.Dom.setStyle(data_div,'opacity','0.3');});
46 YAHOO.util.Dom.setStyle(data_div,'opacity','1');}},null); return false;""")}
46 YAHOO.util.Dom.setStyle(data_div,'opacity','1');}},null); return false;""")}
47 </h2>
47 </h2>
48 </div> No newline at end of file
48 </div>
@@ -1,141 +1,132 b''
1 <%inherit file="/base/base.html"/>
1 <%inherit file="/base/base.html"/>
2 <%!
2 <%!
3 from pylons_app.lib import filters
3 from pylons_app.lib import filters
4 %>
4 %>
5 <%def name="title()">
5 <%def name="title()">
6 ${_('Repository managment')}
6 ${_('Repository managment')}
7 </%def>
7 </%def>
8 <%def name="breadcrumbs()">
8 <%def name="breadcrumbs()">
9 ${h.link_to(u'Home',h.url('/'))}
9 ${h.link_to(u'Home',h.url('/'))}
10 /
10 /
11 ${h.link_to(c.repo_name,h.url('summary_home',repo_name=c.repo_name))}
11 ${h.link_to(c.repo_name,h.url('summary_home',repo_name=c.repo_name))}
12 /
12 /
13 ${_('summary')}
13 ${_('summary')}
14 </%def>
14 </%def>
15 <%def name="page_nav()">
15 <%def name="page_nav()">
16 ${self.menu('summary')}
16 ${self.menu('summary')}
17 </%def>
17 </%def>
18
18
19 <%def name="js()">
19 <%def name="js()">
20 <script type="text/javascript" src="/js/yui/utilities/utilities.js"></script>
20 <script type="text/javascript" src="/js/yui/utilities/utilities.js"></script>
21 <script type="text/javascript">
21 <script type="text/javascript">
22 var E = YAHOO.util.Event;
22 var E = YAHOO.util.Event;
23 var D = YAHOO.util.Dom;
23 var D = YAHOO.util.Dom;
24
24
25 E.onDOMReady(function(e){
25 E.onDOMReady(function(e){
26 id = 'clone_url';
26 id = 'clone_url';
27 E.addListener(id,'click',function(e){
27 E.addListener(id,'click',function(e){
28 D.get('clone_url').select();
28 D.get('clone_url').select();
29 })
29 })
30 })
30 })
31 </script>
31 </script>
32 </%def>
32 </%def>
33
33
34 <%def name="main()">
34 <%def name="main()">
35 <h2 class="no-link no-border">${_('Mercurial Repository Overview')}</h2>
35 <h2 class="no-link no-border">${_('Mercurial Repository Overview')}</h2>
36 <dl class="overview">
36 <dl class="overview">
37 <dt>${_('name')}</dt>
37 <dt>${_('name')}</dt>
38 <dd>${c.repo_info.name}</dd>
38 <dd>${c.repo_info.name}</dd>
39 <dt>${_('description')}</dt>
39 <dt>${_('description')}</dt>
40 <dd>${c.repo_info.description}</dd>
40 <dd>${c.repo_info.description}</dd>
41 <dt>${_('contact')}</dt>
41 <dt>${_('contact')}</dt>
42 <dd>${c.repo_info.contact}</dd>
42 <dd>${c.repo_info.contact}</dd>
43 <dt>${_('last change')}</dt>
43 <dt>${_('last change')}</dt>
44 <dd>${c.repo_info.last_change|n,filters.age} - ${c.repo_info.last_change|n,filters.rfc822date}</dd>
44 <dd>${c.repo_info.last_change|n,filters.age} - ${c.repo_info.last_change|n,filters.rfc822date}</dd>
45 <dt>${_('clone url')}</dt>
45 <dt>${_('clone url')}</dt>
46 <dd><input type="text" id="clone_url" readonly="readonly" value="hg clone ${c.clone_repo_url}" size="70"/></dd>
46 <dd><input type="text" id="clone_url" readonly="readonly" value="hg clone ${c.clone_repo_url}" size="70"/></dd>
47 <dt>${_('download')}</dt>
47 <dt>${_('download')}</dt>
48 <dd>
48 <dd>
49 %for cnt,archive in enumerate(c.repo_info._get_archives()):
49 %for cnt,archive in enumerate(c.repo_info._get_archives()):
50 %if cnt >=1:
50 %if cnt >=1:
51 |
51 |
52 %endif
52 %endif
53 ${h.link_to(c.repo_info.name+'.'+archive['type'],
53 ${h.link_to(c.repo_info.name+'.'+archive['type'],
54 h.url('files_archive_home',repo_name=c.repo_info.name,
54 h.url('files_archive_home',repo_name=c.repo_info.name,
55 revision='tip',fileformat=archive['extension']),class_="archive_logo")}
55 revision='tip',fileformat=archive['extension']),class_="archive_logo")}
56 %endfor
56 %endfor
57 </dd>
57 </dd>
58 <dt>${_('feeds')}</dt>
58 <dt>${_('feeds')}</dt>
59 <dd>
59 <dd>
60 ${h.link_to(_('RSS'),h.url('rss_feed_home',repo_name=c.repo_info.name),class_='rss_logo')}
60 ${h.link_to(_('RSS'),h.url('rss_feed_home',repo_name=c.repo_info.name),class_='rss_logo')}
61 ${h.link_to(_('Atom'),h.url('atom_feed_home',repo_name=c.repo_info.name),class_='atom_logo')}
61 ${h.link_to(_('Atom'),h.url('atom_feed_home',repo_name=c.repo_info.name),class_='atom_logo')}
62 </dd>
62 </dd>
63 </dl>
63 </dl>
64
64
65 <h2>${h.link_to(_('Changes'),h.url('changelog_home',repo_name=c.repo_name))}</h2>
65 <h2>${h.link_to(_('Changes'),h.url('changelog_home',repo_name=c.repo_name))}</h2>
66 <table>
66 <table>
67 <%def name="message_slug(msg)">
68 <%
69 limit = 60
70 if len(msg) > limit:
71 return msg[:limit]+'...'
72 else:
73 return msg
74 %>
75 </%def>
76 %for cnt,cs in enumerate(c.repo_changesets):
67 %for cnt,cs in enumerate(c.repo_changesets):
77 <tr class="parity${cnt%2}">
68 <tr class="parity${cnt%2}">
78 <td>${cs._ctx.date()|n,filters.age}</td>
69 <td>${cs._ctx.date()|n,filters.age}</td>
79 <td>${cs.author|n,filters.person}</td>
70 <td>${cs.author|n,filters.person}</td>
80 <td>r${cs.revision}</td>
71 <td>r${cs.revision}</td>
81 <td>
72 <td>
82 ${h.link_to(message_slug(cs.message),
73 ${h.link_to(truncate(cs.message,60),
83 h.url('changeset_home',repo_name=c.repo_name,revision=cs._short),
74 h.url('changeset_home',repo_name=c.repo_name,revision=cs._short),
84 title=cs.message)}
75 title=cs.message)}
85 </td>
76 </td>
86 <td>
77 <td>
87 <span class="logtags">
78 <span class="logtags">
88 <span class="branchtag">${cs.branch}</span>
79 <span class="branchtag">${cs.branch}</span>
89 %for tag in cs.tags:
80 %for tag in cs.tags:
90 <span class="tagtag">${tag}</span>
81 <span class="tagtag">${tag}</span>
91 %endfor
82 %endfor
92 </span>
83 </span>
93 </td>
84 </td>
94 <td class="nowrap">
85 <td class="nowrap">
95 ${h.link_to(_('changeset'),h.url('changeset_home',repo_name=c.repo_name,revision=cs._short))}
86 ${h.link_to(_('changeset'),h.url('changeset_home',repo_name=c.repo_name,revision=cs._short))}
96 |
87 |
97 ${h.link_to(_('files'),h.url('files_home',repo_name=c.repo_name,revision=cs._short))}
88 ${h.link_to(_('files'),h.url('files_home',repo_name=c.repo_name,revision=cs._short))}
98 </td>
89 </td>
99 </tr>
90 </tr>
100 %endfor
91 %endfor
101 </table>
92 </table>
102
93
103 <h2>${h.link_to(_('Tags'),h.url('tags_home',repo_name=c.repo_name))}</h2>
94 <h2>${h.link_to(_('Tags'),h.url('tags_home',repo_name=c.repo_name))}</h2>
104 <table>
95 <table>
105 %for cnt,tag in enumerate(c.repo_tags):
96 %for cnt,tag in enumerate(c.repo_tags):
106 <tr class="parity${cnt%2}">
97 <tr class="parity${cnt%2}">
107 <td>${tag._ctx.date()|n,filters.age}</td>
98 <td>${tag._ctx.date()|n,filters.age}</td>
108 <td>
99 <td>
109 <span class="logtags">
100 <span class="logtags">
110 <span class="tagtag">${h.link_to(tag.tags[-1],h.url('changeset_home',repo_name=c.repo_name,revision=tag._short))}</span>
101 <span class="tagtag">${h.link_to(tag.tags[-1],h.url('changeset_home',repo_name=c.repo_name,revision=tag._short))}</span>
111 </span>
102 </span>
112 </td>
103 </td>
113 <td class="nowrap">
104 <td class="nowrap">
114 ${h.link_to(_('changeset'),h.url('changeset_home',repo_name=c.repo_name,revision=tag._short))}
105 ${h.link_to(_('changeset'),h.url('changeset_home',repo_name=c.repo_name,revision=tag._short))}
115 |
106 |
116 ${h.link_to(_('files'),h.url('files_home',repo_name=c.repo_name,revision=tag._short))}
107 ${h.link_to(_('files'),h.url('files_home',repo_name=c.repo_name,revision=tag._short))}
117 </td>
108 </td>
118 </tr>
109 </tr>
119 %endfor
110 %endfor
120 </table>
111 </table>
121
112
122 <h2>${h.link_to(_('Branches'),h.url('branches_home',repo_name=c.repo_name))}</h2>
113 <h2>${h.link_to(_('Branches'),h.url('branches_home',repo_name=c.repo_name))}</h2>
123 <table>
114 <table>
124 %for cnt,branch in enumerate(c.repo_branches):
115 %for cnt,branch in enumerate(c.repo_branches):
125 <tr class="parity${cnt%2}">
116 <tr class="parity${cnt%2}">
126 <td>${branch._ctx.date()|n,filters.age}</td>
117 <td>${branch._ctx.date()|n,filters.age}</td>
127 <td>
118 <td>
128 <span class="logtags">
119 <span class="logtags">
129 <span class="branchtag">${h.link_to(branch.branch,h.url('changeset_home',repo_name=c.repo_name,revision=branch._short))}</span>
120 <span class="branchtag">${h.link_to(branch.branch,h.url('changeset_home',repo_name=c.repo_name,revision=branch._short))}</span>
130 </span>
121 </span>
131 </td>
122 </td>
132 <td class="nowrap">
123 <td class="nowrap">
133 ${h.link_to(_('changeset'),h.url('changeset_home',repo_name=c.repo_name,revision=branch._short))}
124 ${h.link_to(_('changeset'),h.url('changeset_home',repo_name=c.repo_name,revision=branch._short))}
134 |
125 |
135 ${h.link_to(_('files'),h.url('files_home',repo_name=c.repo_name,revision=branch._short))}
126 ${h.link_to(_('files'),h.url('files_home',repo_name=c.repo_name,revision=branch._short))}
136 </td>
127 </td>
137 </tr>
128 </tr>
138 %endfor
129 %endfor
139 </table>
130 </table>
140
131
141 </%def> No newline at end of file
132 </%def>
General Comments 0
You need to be logged in to leave comments. Login now