Merge lp:~adiroiban/launchpad/bug-435165 into lp:launchpad
- bug-435165
- Merge into devel
Status: | Merged |
---|---|
Approved by: | Henning Eggers |
Approved revision: | not available |
Merged at revision: | not available |
Proposed branch: | lp:~adiroiban/launchpad/bug-435165 |
Merge into: | lp:launchpad |
Diff against target: |
320 lines (+194/-25) 3 files modified
lib/lp/translations/browser/potemplate.py (+29/-4) lib/lp/translations/stories/standalone/xx-potemplate-index.txt (+162/-19) lib/lp/translations/templates/potemplate-index.pt (+3/-2) |
To merge this branch: | bzr merge lp:~adiroiban/launchpad/bug-435165 |
Related bugs: |
Reviewer | Review Type | Date Requested | Status |
---|---|---|---|
Henning Eggers (community) | code | Approve | |
Review via email: mp+16084@code.launchpad.net |
Commit message
From the template index page, add a link to the listing of all templates from the same source package.
Description of the change
Adi Roiban (adiroiban) wrote : | # |
Henning Eggers (henninge) wrote : | # |
Hi Adi,
thanks for doing this and improving the page handling in this way. This is really a nice addition. As discussed on IRC, please remove the request/URL/5 from the template. Also, I don't like checking conditions on more_templates_
Just some small comments on comments. ;)
> +Visiting any template from the same page, user see link to the other
> +templates.
> +
"the user sees a link" ... ;)
> +For five template, the page displays the first four templates in
> +alphabetical order, and a link to the page listing all templates.
> +
> +Another template is added to the same source package to test this behaviour.
> +
Just write "Another template is added to the same source package." No need to mention that this is a test because we already know it is ... ;) This appears twice.
Thank you for adding all the formatting fixes and making our code look prettier. Good job!
Henning
Adi Roiban (adiroiban) wrote : | # |
Thanks for the review!
Here is the latest diff.
=== modified file 'lib/lp/
--- lib/lp/
+++ lib/lp/
@@ -286,12 +286,25 @@
if (by_source_count > self.SHOW_
other = by_source_count - self.SHOW_
+ if (self.context.
+ # XXX adiroiban 2009-12-21 bug=499058: A canonical_url for
+ # SourcePackageName is needed to avoid hardcoding this URL.
+ url = (canonical_url(
+ self.context.
+ "/+source/" + self.context.
+ "/+translations")
+ else:
+ url = canonical_url(
+ self.context.
+ rootsite=
+ view_name=
if other == 1:
- return "one other template"
+ return " and <a href=\"%s\">one other template</a>." % url
else:
- return "%d other templates" % other
+ return " and <a href=\"%s\">%d other templates</a>." % (
+ url, other)
else:
- return None
+ return ""
@property
def related_
=== modified file 'lib/lp/
--- lib/lp/
+++ lib/lp/
@@ -114,7 +114,7 @@
When the branch or the source package contains less than five templates
they are all displayed on the template page.
-A source package with for templates are created.
+A source package with five templates is created.
>>> from zope.component import getUtility
>>> from canonical.
@@ -140,7 +140,7 @@
... sourcepackagena
>>> logout()
-Visiting any template from the same page, user see link to the other
+Visiting any template from the same page, user sees link to the other
templates.
>>> browser.open(
@@ -155,7 +155,7 @@
For five template, the page displays the first four templates in
alphabetical order, and a link to the page listing all templates.
-Another template is added to the same source package to test this behaviour.
+Another template is added to the same source package.
>>> login('<email address hidden>')
>>> template = factory.
@@ -179,7 +179,7 @@
alphabetical order, and a link to the page listing
all templates, stating the number of other templates.
-Another template is added to the same source package to test this behaviour.
+Another template is added to the same source package.
>>> login('<email address hidden>')
>>> template = factory.
@@ -204,6 +204,48 @@
...
Henning Eggers (henninge) wrote : | # |
Great work, Adi!
This will be able to land but I still have a few minor comments, sorry. ;)
> === modified file 'lib/lp/
> --- lib/lp/
> +++ lib/lp/
> @@ -282,9 +282,29 @@
> return by_source
>
> @property
> - def has_more_
> + def more_templates_
Please add a docstring. I also wonder if the fact that this returns a string and not "a list of templates" should be reflected in the function name.
[...]
The implementation is very good!
> === modified file 'lib/lp/
> --- lib/lp/
> +++ lib/lp/
[...]
> +Visiting any template from the same page, user sees link to the other
> +templates.
I am sorry but this sentence is still missing a word or two. My last suggestion was probably missleading as you are talking about multiple links. So a complete sentence would be:
"..., the user sees links to the other templates."
> +
> + >>> browser.open(
> + ... ("http://
> + ... "ubuntu/
> + ... package.name, template.name))
> + >>> relatives = find_tag_by_id(
> + ... browser.contents, 'potemplate-
> + >>> print extract_
> + Other templates here: first, forth, second, third
> +
> +For five template, the page displays the first four templates in
> +alphabetical order, and a link to the page listing all templates.
"five templates" ;-) Rember, only two plural forms in English ... ;)
[...]
> +For more than five template, the page displays the first four templates in
"five templates" ... ;)
[...]
> --- lib/lp/
> +++ lib/lp/
> @@ -47,8 +47,9 @@
> tal:content=
> </a><tal:comma condition="not: repeat/pot/end">,
> </tal:comma>
> - --><tal:more condition=
> - >...</tal:more>
> + --><tal:
I am sorry, I gave you the wrong hint here. It should be "replace" instead of "content". No need to have the <tal:more-
> + and <a href="#">17 other templates</a>
> + </tal:more-
> </p>
> </div>
>
Thanks again for the branch!
Henning
Adi Roiban (adiroiban) wrote : | # |
Hi Henning,
Here is the latest diff.
I went for "more_templates
=== modified file 'lib/lp/
--- lib/lp/
+++ lib/lp/
@@ -282,7 +282,7 @@
return by_source
@property
- def more_templates_
+ def more_templates_
if (by_source_count > self.SHOW_
other = by_source_count - self.SHOW_
=== modified file 'lib/lp/
--- lib/lp/
+++ lib/lp/
@@ -140,7 +140,7 @@
... sourcepackagena
>>> logout()
-Visiting any template from the same page, user sees link to the other
+Visiting any template from the same page, the user sees links to the other
templates.
>>> browser.open(
@@ -152,7 +152,7 @@
>>> print extract_
Other templates here: first, forth, second, third
-For five template, the page displays the first four templates in
+For five templates, the page displays the first four templates in
alphabetical order, and a link to the page listing all templates.
Another template is added to the same source package.
@@ -175,7 +175,7 @@
>>> browser.
-For more than five template, the page displays the first four templates in
+For more than five templates, the page displays the first four templates in
alphabetical order, and a link to the page listing
all templates, stating the number of other templates.
=== modified file 'lib/lp/
--- lib/lp/
+++ lib/lp/
@@ -47,7 +47,7 @@
- --><tal:
+ --><tal:
and <a href="#">17 other templates</a>
</p>
Adi Roiban (adiroiban) wrote : | # |
Here is the dot.
=== modified file 'lib/lp/
--- lib/lp/
+++ lib/lp/
@@ -299,9 +299,9 @@
if other == 1:
- return " and <a href=\"%s\">one other template</a>." % url
+ return " and <a href=\"%s\">one other template</a>" % url
else:
- return " and <a href=\"%s\">%d other templates</a>." % (
+ return " and <a href=\"%s\">%d other templates</a>" % (
else:
return ""
=== modified file 'lib/lp/
--- lib/lp/
+++ lib/lp/
@@ -74,7 +74,7 @@
>>> alternate_notice = find_tag_
... 'potemplate-
>>> print extract_
- Other templates here: evolution-2.2
+ Other templates here: evolution-2.2.
The notice links to the alternate template.
@@ -150,7 +150,7 @@
>>> relatives = find_tag_by_id(
... browser.contents, 'potemplate-
>>> print extract_
- Other templates here: first, forth, second, third
+ Other templates here: first, forth, second, third.
For five templates, the page displays the first four templates in
alphabetical order, and a link to the page listing all templates.
=== modified file 'lib/lp/
--- lib/lp/
+++ lib/lp/
@@ -49,7 +49,7 @@
and <a href="#">17 other templates</a>
- </tal:more-
+ </tal:more-
</p>
</div>
Preview Diff
1 | === modified file 'lib/lp/translations/browser/potemplate.py' |
2 | --- lib/lp/translations/browser/potemplate.py 2009-12-09 01:03:22 +0000 |
3 | +++ lib/lp/translations/browser/potemplate.py 2009-12-22 10:31:17 +0000 |
4 | @@ -282,9 +282,29 @@ |
5 | return by_source |
6 | |
7 | @property |
8 | - def has_more_templates_by_source(self): |
9 | + def more_templates_by_source_link(self): |
10 | by_source_count = self.context.relatives_by_source.count() |
11 | - return by_source_count > self.SHOW_RELATED_TEMPLATES |
12 | + if (by_source_count > self.SHOW_RELATED_TEMPLATES): |
13 | + other = by_source_count - self.SHOW_RELATED_TEMPLATES |
14 | + if (self.context.distroseries): |
15 | + # XXX adiroiban 2009-12-21 bug=499058: A canonical_url for |
16 | + # SourcePackageName is needed to avoid hardcoding this URL. |
17 | + url = (canonical_url( |
18 | + self.context.distroseries, rootsite="translations") + |
19 | + "/+source/" + self.context.sourcepackagename.name + |
20 | + "/+translations") |
21 | + else: |
22 | + url = canonical_url( |
23 | + self.context.productseries, |
24 | + rootsite="translations", |
25 | + view_name="+templates") |
26 | + if other == 1: |
27 | + return " and <a href=\"%s\">one other template</a>" % url |
28 | + else: |
29 | + return " and <a href=\"%s\">%d other templates</a>" % ( |
30 | + url, other) |
31 | + else: |
32 | + return "" |
33 | |
34 | @property |
35 | def related_templates_by_name(self): |
36 | @@ -438,7 +458,7 @@ |
37 | warning = ( |
38 | "A file could not be uploaded because its " |
39 | "name matched multiple existing uploads, for " |
40 | - "different templates." ) |
41 | + "different templates.") |
42 | ul_conflicts = ( |
43 | "The conflicting file name was:<br /> " |
44 | "<ul><li>%s</li></ul>" % cgi.escape(conflicts[0])) |
45 | @@ -482,9 +502,12 @@ |
46 | |
47 | |
48 | class POTemplateViewPreferred(POTemplateView): |
49 | + """View class that shows only users preferred templates.""" |
50 | + |
51 | def pofiles(self): |
52 | return POTemplateView.pofiles(self, preferred_only=True) |
53 | |
54 | + |
55 | class POTemplateEditView(LaunchpadEditFormView): |
56 | """View class that lets you edit a POTemplate object.""" |
57 | |
58 | @@ -548,7 +571,7 @@ |
59 | if what == 'all': |
60 | export_potemplate = True |
61 | |
62 | - pofiles = self.context.pofiles |
63 | + pofiles = self.context.pofiles |
64 | elif what == 'some': |
65 | pofiles = [] |
66 | export_potemplate = 'potemplate' in self.request.form |
67 | @@ -580,6 +603,7 @@ |
68 | """Return a list of PO files available for export.""" |
69 | |
70 | class BrowserPOFile: |
71 | + |
72 | def __init__(self, value, browsername): |
73 | self.value = value |
74 | self.browsername = browsername |
75 | @@ -699,6 +723,7 @@ |
76 | |
77 | class POTemplateBreadcrumb(Breadcrumb): |
78 | """Breadcrumb for `IPOTemplate`.""" |
79 | + |
80 | @property |
81 | def text(self): |
82 | return smartquote('Template "%s"' % self.context.name) |
83 | |
84 | === modified file 'lib/lp/translations/stories/standalone/xx-potemplate-index.txt' |
85 | --- lib/lp/translations/stories/standalone/xx-potemplate-index.txt 2009-12-10 12:46:11 +0000 |
86 | +++ lib/lp/translations/stories/standalone/xx-potemplate-index.txt 2009-12-22 10:31:17 +0000 |
87 | @@ -44,23 +44,6 @@ |
88 | Xhosa 22 ... ... ... — |
89 | Zulu 22 ... ... — — |
90 | |
91 | -When products have more than one template, the page informs the user |
92 | -that there are alternates that may be translated. |
93 | - |
94 | - >>> anon_browser.open("http://translations.launchpad.dev/" |
95 | - ... "evolution/trunk/+pots/evolution-2.2-test") |
96 | - >>> alternate_notice = find_tag_by_id(anon_browser.contents, |
97 | - ... 'potemplate-relatives') |
98 | - >>> print extract_text(alternate_notice) |
99 | - Other templates here: evolution-2.2 |
100 | - |
101 | -The notice links to the alternate template. |
102 | - |
103 | - >>> print alternate_notice |
104 | - <p...> |
105 | - <span>Other templates here:</span> |
106 | - <a href="/evolution/trunk/+pots/evolution-2.2">evolution-2.2</a>... |
107 | - </p> |
108 | |
109 | English is not translatable. We do not display English in the list of |
110 | languages when the user speaks English or even when English |
111 | @@ -80,13 +63,36 @@ |
112 | Finnish ... ... ... ... P\xf6ll\xe4 |
113 | |
114 | |
115 | +Finding related templates |
116 | +------------------------- |
117 | + |
118 | +When products have more than one template, the page informs the user |
119 | +that there are alternates that may be translated. |
120 | + |
121 | + >>> anon_browser.open("http://translations.launchpad.dev/" |
122 | + ... "evolution/trunk/+pots/evolution-2.2-test") |
123 | + >>> alternate_notice = find_tag_by_id(anon_browser.contents, |
124 | + ... 'potemplate-relatives') |
125 | + >>> print extract_text(alternate_notice) |
126 | + Other templates here: evolution-2.2. |
127 | + |
128 | +The notice links to the alternate template. |
129 | + |
130 | + >>> print alternate_notice |
131 | + <p...> |
132 | + <span>Other templates here:</span> |
133 | + <a href="/evolution/trunk/+pots/evolution-2.2">evolution-2.2</a>... |
134 | + </p> |
135 | + |
136 | + |
137 | DistroSeries and ProductSeries links to related templates |
138 | --------------------------------------------------------- |
139 | |
140 | We are presented not only with links to alternate templates from the same |
141 | source, but also with links to the same template in (other) distroseries. |
142 | |
143 | - >>> anon_browser.open('http://translations.launchpad.dev/evolution/trunk/+pots/evolution-2.2') |
144 | + >>> anon_browser.open('http://translations.launchpad.dev/evolution' |
145 | + ... '/trunk/+pots/evolution-2.2') |
146 | >>> alternate_notice = find_tag_by_id(anon_browser.contents, |
147 | ... 'potemplate-rel-by-name') |
148 | >>> print extract_text(alternate_notice) |
149 | @@ -96,7 +102,8 @@ |
150 | |
151 | The template in the other distroseries links back to this one. |
152 | |
153 | - >>> anon_browser.open('http://translations.launchpad.dev/ubuntu/hoary/+source/evolution/+pots/evolution-2.2') |
154 | + >>> anon_browser.open('http://translations.launchpad.dev/ubuntu' |
155 | + ... '/hoary/+source/evolution/+pots/evolution-2.2') |
156 | >>> alternate_notice = find_tag_by_id(anon_browser.contents, |
157 | ... 'potemplate-rel-by-name') |
158 | >>> print extract_text(alternate_notice) |
159 | @@ -104,6 +111,141 @@ |
160 | >>> print alternate_notice |
161 | <p...<a href="/evolution/trunk/+pots/evolution-2.2"... |
162 | |
163 | +When the branch or the source package contains less than five templates |
164 | +they are all displayed on the template page. |
165 | + |
166 | +A source package with five templates is created. |
167 | + |
168 | + >>> from zope.component import getUtility |
169 | + >>> from canonical.launchpad.interfaces.launchpad import ( |
170 | + ... ILaunchpadCelebrities) |
171 | + >>> login('admin@canonical.com') |
172 | + >>> ubuntu = getUtility(ILaunchpadCelebrities).ubuntu |
173 | + >>> hoary = ubuntu.getSeries('hoary') |
174 | + >>> package = factory.makeSourcePackage(distroseries=hoary) |
175 | + >>> template = factory.makePOTemplate( |
176 | + ... distroseries=hoary, |
177 | + ... sourcepackagename=package.sourcepackagename, name='first') |
178 | + >>> template = factory.makePOTemplate( |
179 | + ... distroseries=hoary, |
180 | + ... sourcepackagename=package.sourcepackagename, name='second') |
181 | + >>> template = factory.makePOTemplate( |
182 | + ... distroseries=hoary, |
183 | + ... sourcepackagename=package.sourcepackagename, name='third') |
184 | + >>> template = factory.makePOTemplate( |
185 | + ... distroseries=hoary, |
186 | + ... sourcepackagename=package.sourcepackagename, name='forth') |
187 | + >>> template = factory.makePOTemplate( |
188 | + ... distroseries=hoary, |
189 | + ... sourcepackagename=package.sourcepackagename, name='fifth') |
190 | + >>> logout() |
191 | + |
192 | +Visiting any template from the same page, the user sees links to the other |
193 | +templates. |
194 | + |
195 | + >>> browser.open( |
196 | + ... ("http://translations.launchpad.dev/" |
197 | + ... "ubuntu/hoary/+source/%s/+pots/%s") % ( |
198 | + ... package.name, template.name)) |
199 | + >>> relatives = find_tag_by_id( |
200 | + ... browser.contents, 'potemplate-relatives') |
201 | + >>> print extract_text(relatives) |
202 | + Other templates here: first, forth, second, third. |
203 | + |
204 | +For five templates, the page displays the first four templates in |
205 | +alphabetical order, and a link to the page listing all templates. |
206 | + |
207 | +Another template is added to the same source package. |
208 | + |
209 | + >>> login('admin@canonical.com') |
210 | + >>> template = factory.makePOTemplate( |
211 | + ... distroseries=hoary, |
212 | + ... sourcepackagename=package.sourcepackagename, name='sixth') |
213 | + >>> logout() |
214 | + |
215 | + >>> browser.open( |
216 | + ... ("http://translations.launchpad.dev/" |
217 | + ... "ubuntu/hoary/+source/%s/+pots/%s") % ( |
218 | + ... package.name, template.name)) |
219 | + >>> relatives = find_tag_by_id( |
220 | + ... browser.contents, 'potemplate-relatives') |
221 | + >>> print extract_text(relatives) |
222 | + Other templates here: fifth, first, forth, second |
223 | + and one other template. |
224 | + |
225 | + >>> browser.getLink('one other template').click() |
226 | + |
227 | +For more than five templates, the page displays the first four templates in |
228 | +alphabetical order, and a link to the page listing |
229 | +all templates, stating the number of other templates. |
230 | + |
231 | +Another template is added to the same source package. |
232 | + |
233 | + >>> login('admin@canonical.com') |
234 | + >>> template = factory.makePOTemplate( |
235 | + ... distroseries=hoary, |
236 | + ... sourcepackagename=package.sourcepackagename, name='seventh') |
237 | + >>> logout() |
238 | + |
239 | + >>> browser.open(( |
240 | + ... "http://translations.launchpad.dev/" |
241 | + ... "ubuntu/hoary/+source/%s/+pots/%s") % ( |
242 | + ... package.name, template.name)) |
243 | + >>> relatives = find_tag_by_id( |
244 | + ... browser.contents, 'potemplate-relatives') |
245 | + >>> print extract_text(relatives) |
246 | + Other templates here: fifth, first, forth, second |
247 | + and 2 other templates. |
248 | + |
249 | + >>> browser.getLink('2 other templates').click() |
250 | + >>> browser.url == (( |
251 | + ... 'http://translations.launchpad.dev/' |
252 | + ... 'ubuntu/hoary/+source/%s/+translations') % ( |
253 | + ... package.name)) |
254 | + True |
255 | + |
256 | +The "other templates" link for product series templates is leading to a |
257 | +page showing all templates for that product series. |
258 | + |
259 | +A product series with 7 templates is created. |
260 | + |
261 | + >>> from zope.component import getUtility |
262 | + >>> from canonical.launchpad.interfaces.launchpad import ( |
263 | + ... ILaunchpadCelebrities) |
264 | + >>> login('admin@canonical.com') |
265 | + >>> product = factory.makeProduct(name="fusa", official_rosetta=True) |
266 | + >>> product_trunk = product.getSeries('trunk') |
267 | + >>> template = factory.makePOTemplate( |
268 | + ... productseries=product_trunk, name='first') |
269 | + >>> template = factory.makePOTemplate( |
270 | + ... productseries=product_trunk, name='second') |
271 | + >>> template = factory.makePOTemplate( |
272 | + ... productseries=product_trunk, name='third') |
273 | + >>> template = factory.makePOTemplate( |
274 | + ... productseries=product_trunk, name='forth') |
275 | + >>> template = factory.makePOTemplate( |
276 | + ... productseries=product_trunk, name='fifth') |
277 | + >>> template = factory.makePOTemplate( |
278 | + ... productseries=product_trunk, name='sixth') |
279 | + >>> template = factory.makePOTemplate( |
280 | + ... productseries=product_trunk, name='seventh') |
281 | + >>> logout() |
282 | + |
283 | + >>> browser.open(( |
284 | + ... "http://translations.launchpad.dev/" |
285 | + ... "fusa/trunk/+pots/%s") % template.name) |
286 | + >>> relatives = find_tag_by_id( |
287 | + ... browser.contents, 'potemplate-relatives') |
288 | + >>> print extract_text(relatives) |
289 | + Other templates here: fifth, first, forth, second |
290 | + and 2 other templates. |
291 | + |
292 | + >>> browser.getLink('2 other templates').click() |
293 | + >>> browser.url == ( |
294 | + ... 'http://translations.launchpad.dev/' |
295 | + ... 'fusa/trunk/+templates') |
296 | + True |
297 | + |
298 | |
299 | Administering templates |
300 | ----------------------- |
301 | @@ -164,3 +306,4 @@ |
302 | >>> print admin_browser.url |
303 | http://translations.launchpad.dev/ubuntu/+settings |
304 | |
305 | + |
306 | |
307 | === modified file 'lib/lp/translations/templates/potemplate-index.pt' |
308 | --- lib/lp/translations/templates/potemplate-index.pt 2009-12-07 21:58:53 +0000 |
309 | +++ lib/lp/translations/templates/potemplate-index.pt 2009-12-22 10:31:17 +0000 |
310 | @@ -47,8 +47,9 @@ |
311 | tal:content="pot/name">A POTemplate |
312 | </a><tal:comma condition="not: repeat/pot/end">, |
313 | </tal:comma></tal:relatives_by_source><!-- |
314 | - --><tal:more condition="view/has_more_templates_by_source" |
315 | - >...</tal:more> |
316 | + --><tal:more-templates replace="structure view/more_templates_by_source_link"> |
317 | + and <a href="#">17 other templates</a> |
318 | + </tal:more-templates>. |
319 | </p> |
320 | </div> |
321 |
= Bug 435165 =
Currently, if I go to a template page of a source page with multiple templates, the list of templates shown under the "Related templates" section is truncated if the list is long. I think this is a nice feature, which avoids unnecessary clutter.
Example: https:/ /translations. edge.launchpad. net/ubuntu/ karmic/ +source/ kdelibs/ +pots/kdelibs
At the same time though, there is currently no easy way to navigate to the full list of templates.
== Proposed fix ==
Instead of the ellipsis from the end, add a text like "and _3 other templates_." which links to a full list.
== Tests == potemplate- index
lp-test -t rosetta-
== Demo and Q/A ==
Screenshot for UI review: http:// launchpadlibrar ian.net/ 36610283/ others. jpg
It is not trivial to add and enable new potemplates from LP UI as they are imported by a cron script.
The story describes a way of adding new templates and testing the behaviour.
= Launchpad lint =
Checking for conflicts. and issues in doctests and templates.
Running jslint, xmllint, pyflakes, and pylint.
Using normal rules.
Linting changed files: translations/ browser/ potemplate. py translations/ stories/ standalone/ xx-rosetta- potemplate- index.txt
lib/lp/
lib/lp/