Merge lp:~danilo/launchpad/translator-templates into lp:launchpad

Proposed by Данило Шеган
Status: Merged
Merged at revision: not available
Proposed branch: lp:~danilo/launchpad/translator-templates
Merge into: lp:launchpad
Diff against target: None lines
To merge this branch: bzr merge lp:~danilo/launchpad/translator-templates
Reviewer Review Type Date Requested Status
Henning Eggers (community) code Approve
Review via email: mp+10546@code.launchpad.net
To post a comment you must log in.
Revision history for this message
Данило Шеган (danilo) wrote :

= Bug #417070 =

Translator views (all LaunchpadEditForm views) should be migrated to
3.0 UI. We are doing no further improvements on them, just mechanical
changes.

== Proposed fix ==

Get rid of translator-admin.pt, translator-edit.pt and
translator-remove.pt and use generic-edit.pt instead to migrate to 3.0
UI.

== Implementation details ==

Since Translator objects don't provide canonical_urls, the new logo
rendering stuff fails with NoCanonicalUrl. A solution is simple:
ignore it in
  canonical.lazr.canonicalurl.nearest_provides_or_adapted

Tim has done a similar change to
  canonical.launchpad.webapp.publisher.nearest
for the same problem, but that means we might have a problem in
the infrastructure somewhere.

Everything else is mostly mechanical changes to switch to the new layout.

== Tests ==

bin/test -vvt translator-views

== Demo and Q/A ==

Go to
  https://translations.edge.launchpad.net/+groups/launchpad-translators
and look at admin, edit and remove pages.

(or, on https://translations.launchpad.dev/+groups/testing-translation-team)

= Launchpad lint =

Checking for conflicts. and issues in doctests and templates.
Running jslint, xmllint, pyflakes, and pylint.
Using normal rules.

Linting changed files:
  lib/lp/translations/browser/configure.zcml
  lib/canonical/launchpad/pagetitles.py
  lib/canonical/lazr/canonicalurl.py
  lib/lp/testing/factory.py
  lib/lp/translations/browser/translator.py
  lib/lp/translations/stories/translationgroups/xx-link-to-documentation.txt
  lib/lp/translations/browser/tests/translator-views.txt

Revision history for this message
Henning Eggers (henninge) wrote :

Thanks you for starting on the template conversion for translations! Hope people will stop worrying soon ... ;-)

This branch is good to land but please consider these comments.

Please talk to Curtis as you already intended to see if there is an alternative to hacking lazr code.

> + except NoCanonicalUrl:

> + # Drop out of the try-except and return None like it would otherwise.

> + pass

If that hack stays in there, please replace this pseudo-code comment with something that really explains why this exception is ignored.

Cheers,
Henning

review: Approve (code)

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1=== modified file 'lib/canonical/launchpad/pagetitles.py'
2--- lib/canonical/launchpad/pagetitles.py 2009-08-21 09:39:13 +0000
3+++ lib/canonical/launchpad/pagetitles.py 2009-08-21 18:15:20 +0000
4@@ -1396,20 +1396,4 @@
5 context.pofile.potemplate.displayname,
6 context.pofile.language.englishname)
7
8-def translator_admin(context, view):
9- """Return the page title for administering a translator in a group."""
10- return "Administer %s translator for %s" % (
11- context.language.englishname, context.translationgroup.title)
12-
13-def translator_edit(context, view):
14- """Return the page title for editing a the translator details."""
15- return "Edit %s translator for %s" % (
16- context.language.englishname, context.translationgroup.title)
17-
18-def translator_remove(context, view):
19- """Return the page title to remove a translator from a group."""
20- return "Remove %s as the %s translator for %s" % (
21- context.translator.displayname, context.language.englishname,
22- context.translationgroup.title)
23-
24 unauthorized = 'Error: Not authorized'
25
26=== modified file 'lib/canonical/lazr/canonicalurl.py'
27--- lib/canonical/lazr/canonicalurl.py 2009-08-19 05:33:26 +0000
28+++ lib/canonical/lazr/canonicalurl.py 2009-08-21 18:06:18 +0000
29@@ -18,6 +18,7 @@
30 # This function should be moved into lazr.canonicalurl.
31 # See bug #185958.
32 from canonical.launchpad.webapp.publisher import canonical_url_iterator
33+from canonical.launchpad.webapp.interfaces import NoCanonicalUrl
34
35
36 def nearest_context_with_adapter(obj, interface, name=u''):
37@@ -58,10 +59,16 @@
38 :return None: if there is no object that provides or can be adapted in
39 the url chain.
40 """
41- for curr_obj in canonical_url_iterator(obj):
42- # If the curr_obj implements the interface, it is returned.
43- impl = interface(curr_obj, None)
44- if impl is not None:
45- return impl
46-
47+ # XXX 20090821 Danilo: a note for reviewer to remind me about this being
48+ # quite similar code to canonical.launchpad.webapp.publisher.nearest
49+ # to check with Curtis if new templating stuff should use that instead.
50+ try:
51+ for curr_obj in canonical_url_iterator(obj):
52+ # If the curr_obj implements the interface, it is returned.
53+ impl = interface(curr_obj, None)
54+ if impl is not None:
55+ return impl
56+ except NoCanonicalUrl:
57+ # Drop out of the try-except and return None like it would otherwise.
58+ pass
59 return None
60
61=== modified file 'lib/lp/testing/factory.py'
62--- lib/lp/testing/factory.py 2009-08-19 23:11:16 +0000
63+++ lib/lp/testing/factory.py 2009-08-21 18:06:18 +0000
64@@ -443,8 +443,10 @@
65 poll_type=PollAlgorithm.SIMPLE)
66
67 def makeTranslationGroup(
68- self, owner, name=None, title=None, summary=None, url=None):
69+ self, owner=None, name=None, title=None, summary=None, url=None):
70 """Create a new, arbitrary `TranslationGroup`."""
71+ if owner is None:
72+ owner = self.makePerson()
73 if name is None:
74 name = self.getUniqueString("translationgroup")
75 if title is None:
76
77=== modified file 'lib/lp/translations/browser/configure.zcml'
78--- lib/lp/translations/browser/configure.zcml 2009-08-20 08:13:15 +0000
79+++ lib/lp/translations/browser/configure.zcml 2009-08-21 18:06:18 +0000
80@@ -89,21 +89,21 @@
81 for="lp.translations.interfaces.translator.ITranslator"
82 permission="launchpad.Admin"
83 class="lp.translations.browser.translator.TranslatorAdminView"
84- template="../templates/translator-admin.pt"
85+ template="../../app/templates/generic-edit.pt"
86 layer="canonical.launchpad.layers.TranslationsLayer"/>
87 <browser:page
88 name="+edit"
89 for="lp.translations.interfaces.translator.IEditTranslator"
90 permission="launchpad.Edit"
91 class="lp.translations.browser.translator.TranslatorEditView"
92- template="../templates/translator-edit.pt"
93+ template="../../app/templates/generic-edit.pt"
94 layer="canonical.launchpad.layers.TranslationsLayer"/>
95 <browser:page
96 name="+remove"
97 for="lp.translations.interfaces.translator.ITranslator"
98 permission="launchpad.Edit"
99 class="lp.translations.browser.translator.TranslatorRemoveView"
100- template="../templates/translator-remove.pt"
101+ template="../../app/templates/generic-edit.pt"
102 layer="canonical.launchpad.layers.TranslationsLayer"/>
103 </facet>
104 <facet
105
106=== added file 'lib/lp/translations/browser/tests/translator-views.txt'
107--- lib/lp/translations/browser/tests/translator-views.txt 1970-01-01 00:00:00 +0000
108+++ lib/lp/translations/browser/tests/translator-views.txt 2009-08-21 18:06:18 +0000
109@@ -0,0 +1,81 @@
110+Translator views
111+================
112+
113+Translator views provide ways to administrate, edit and remove
114+per-language translation teams in a `TranslationGroup`.
115+
116+ >>> group = factory.makeTranslationGroup(
117+ ... name='test-translators', title=u'Test translators')
118+ >>> team = factory.makeTeam(name='bad-translators',
119+ ... displayname='Bad translators')
120+
121+Serbian translators in 'Test translators' group is the `team`.
122+
123+ >>> from lp.services.worlddata.interfaces.language import ILanguageSet
124+ >>> from lp.translations.interfaces.translator import ITranslatorSet
125+ >>> serbian = getUtility(ILanguageSet).getLanguageByCode('sr')
126+ >>> translator = getUtility(ITranslatorSet).new(
127+ ... group, serbian, team, None)
128+
129+
130+TranslatorAdminView
131+-------------------
132+
133+Translator +admin view provides a nice page title and a form label.
134+
135+ >>> from canonical.launchpad.layers import TranslationsLayer
136+ >>> view = create_initialized_view(translator, '+admin',
137+ ... layer=TranslationsLayer)
138+ >>> print view.label
139+ Edit Serbian translation team in Test translators
140+
141+ >>> print view.page_title
142+ Edit Serbian translation team in Test translators
143+
144+Canceling changes to the Translator takes one back to the group
145+page.
146+
147+ >>> print view.cancel_url
148+ http://translations.launchpad.dev/+groups/test-translators
149+
150+TranslatorEditView
151+------------------
152+
153+Translator +edit view allows one to only set translation guidelines
154+for a language in a TranslationGroup, and page title and form label
155+describe that appropriately.
156+
157+ >>> from canonical.launchpad.layers import TranslationsLayer
158+ >>> view = create_initialized_view(translator, '+edit',
159+ ... layer=TranslationsLayer)
160+ >>> print view.label
161+ Set Serbian guidelines for Test translators
162+
163+ >>> print view.page_title
164+ Set Serbian guidelines for Test translators
165+
166+Canceling changes to the guidelines takes one back to the team page.
167+
168+ >>> print view.cancel_url
169+ http://translations.launchpad.dev/~bad-translators
170+
171+
172+TranslatorRemoveView
173+------------------
174+
175+Translator +edit view allows one to only set translation guidelines
176+for a language in a TranslationGroup.
177+
178+ >>> from canonical.launchpad.layers import TranslationsLayer
179+ >>> view = create_initialized_view(translator, '+remove',
180+ ... layer=TranslationsLayer)
181+ >>> print view.label
182+ Unset 'Bad translators' as the Serbian translator in Test translators
183+
184+ >>> print view.page_title
185+ Unset 'Bad translators' as the Serbian translator in Test translators
186+
187+Canceling removal of a translation team takes one back to the group page.
188+
189+ >>> print view.cancel_url
190+ http://translations.launchpad.dev/+groups/test-translators
191
192=== modified file 'lib/lp/translations/browser/translator.py'
193--- lib/lp/translations/browser/translator.py 2009-07-17 00:26:05 +0000
194+++ lib/lp/translations/browser/translator.py 2009-08-21 18:06:18 +0000
195@@ -17,20 +17,6 @@
196 'TranslatorRemoveView',
197 ]
198
199-class TranslatorEditView(LaunchpadEditFormView):
200- """View class to edit ITranslator objects"""
201-
202- schema = IEditTranslator
203-
204- @action("Change")
205- def change_action(self, action, data):
206- """Edit the translator that does translations for a given language."""
207- self.updateContextFromData(data)
208-
209- @property
210- def next_url(self):
211- return canonical_url(self.context.translator)
212-
213
214 class TranslatorAdminView(LaunchpadEditFormView):
215 """View class to administer ITranslator objects"""
216@@ -62,22 +48,62 @@
217 existing_translator_link))
218
219 @property
220- def next_url(self):
221- return canonical_url(self.context.translationgroup)
222+ def label(self):
223+ """Return form label describing the action one is doing."""
224+ return "Edit %s translation team in %s" % (
225+ self.context.language.englishname,
226+ self.context.translationgroup.title)
227+
228+ @property
229+ def page_title(self):
230+ """Page title for the edit form."""
231+ return self.label
232+
233+ @property
234+ def cancel_url(self):
235+ return canonical_url(self.context.translationgroup,
236+ rootsite='translations')
237+
238+ @property
239+ def next_url(self):
240+ return self.cancel_url
241+
242+
243+class TranslatorEditView(LaunchpadEditFormView):
244+ """View class to edit ITranslator objects"""
245+
246+ schema = IEditTranslator
247+
248+ @action("Set")
249+ def change_action(self, action, data):
250+ """Set the translator guidelines for a given language."""
251+ self.updateContextFromData(data)
252+
253+ @property
254+ def label(self):
255+ """Return form label describing the action one is doing."""
256+ return "Set %s guidelines for %s" % (
257+ self.context.language.englishname,
258+ self.context.translationgroup.title)
259+
260+ @property
261+ def page_title(self):
262+ """Page title for the edit form."""
263+ return self.label
264+
265+ @property
266+ def cancel_url(self):
267+ return canonical_url(self.context.translator, rootsite='translations')
268+
269+ @property
270+ def next_url(self):
271+ return self.cancel_url
272
273
274 class TranslatorRemoveView(LaunchpadFormView):
275 schema = ITranslator
276 field_names = []
277
278- @action("Cancel")
279- def cancel(self, action, data):
280- self.request.response.addInfoNotification(
281- 'Canceled the request to remove %s as the %s translator for %s.' %
282- (self.context.translator.displayname,
283- self.context.language.englishname,
284- self.context.translationgroup.title))
285-
286 @action("Remove")
287 def remove(self, action, data):
288 """Remove the ITranslator from the associated ITranslationGroup."""
289@@ -89,5 +115,23 @@
290 self.request.response.addInfoNotification(message)
291
292 @property
293+ def label(self):
294+ """Return form label describing the action one is doing."""
295+ return "Unset '%s' as the %s translator in %s" % (
296+ self.context.translator.displayname,
297+ self.context.language.englishname,
298+ self.context.translationgroup.title)
299+
300+ @property
301+ def page_title(self):
302+ """Page title for the edit form."""
303+ return self.label
304+
305+ @property
306+ def cancel_url(self):
307+ return canonical_url(self.context.translationgroup,
308+ rootsite='translations')
309+
310+ @property
311 def next_url(self):
312- return canonical_url(self.context.translationgroup)
313+ return self.cancel_url
314
315=== modified file 'lib/lp/translations/stories/translationgroups/xx-link-to-documentation.txt'
316--- lib/lp/translations/stories/translationgroups/xx-link-to-documentation.txt 2009-07-16 11:53:44 +0000
317+++ lib/lp/translations/stories/translationgroups/xx-link-to-documentation.txt 2009-08-21 18:06:18 +0000
318@@ -18,7 +18,7 @@
319 ... 'http://translations.launchpad.dev/'
320 ... '+groups/testing-translation-team/es/+admin')
321 >>> print carlos_browser.title
322- Administer Spanish translator for Just a testing team
323+ Edit Spanish translation team in Just a testing team
324
325 This way he can also set the documentation URL.
326
327@@ -76,7 +76,7 @@
328 ... 'http://translations.launchpad.dev/'
329 ... '+groups/testing-translation-team/eo/+edit')
330 >>> print test_browser.title
331- Edit Esperanto translator for Just a testing team
332+ Set Esperanto guidelines for Just a testing team
333 >>> test_browser.getControl('Translation guidelines').value = (
334 ... 'http://www.launchpad.net/')
335 >>> test_browser.getControl('Change').click()
336
337=== removed file 'lib/lp/translations/templates/translator-admin.pt'
338--- lib/lp/translations/templates/translator-admin.pt 2009-07-17 17:59:07 +0000
339+++ lib/lp/translations/templates/translator-admin.pt 1970-01-01 00:00:00 +0000
340@@ -1,29 +0,0 @@
341-<html
342- xmlns="http://www.w3.org/1999/xhtml"
343- xmlns:tal="http://xml.zope.org/namespaces/tal"
344- xmlns:metal="http://xml.zope.org/namespaces/metal"
345- xmlns:i18n="http://xml.zope.org/namespaces/i18n"
346- xml:lang="en"
347- lang="en"
348- dir="ltr"
349- metal:use-macro="view/macro:page/onecolumn"
350- i18n:domain="launchpad">
351- <body tal:define="context_menu context/menu:context">
352- <div metal:fill-slot="main">
353- <div>
354- <a href="/+groups">Translation groups:</a>
355- <a tal:attributes="href context/translationgroup/fmt:url">
356- <tal:translation-group replace="context/translationgroup/title">
357- Foo bar
358- </tal:translation-group> translation group
359- </a>
360- </div>
361- <h1>
362- Edit the <tal:language replace="context/language/englishname">Spanish
363- </tal:language> translation team
364- </h1>
365-
366- <div metal:use-macro="context/@@launchpad_form/form" />
367- </div>
368- </body>
369-</html>
370
371=== removed file 'lib/lp/translations/templates/translator-edit.pt'
372--- lib/lp/translations/templates/translator-edit.pt 2009-07-17 17:59:07 +0000
373+++ lib/lp/translations/templates/translator-edit.pt 1970-01-01 00:00:00 +0000
374@@ -1,16 +0,0 @@
375-<html
376- xmlns="http://www.w3.org/1999/xhtml"
377- xmlns:tal="http://xml.zope.org/namespaces/tal"
378- xmlns:metal="http://xml.zope.org/namespaces/metal"
379- xmlns:i18n="http://xml.zope.org/namespaces/i18n"
380- xml:lang="en"
381- lang="en"
382- dir="ltr"
383- metal:use-macro="view/macro:page/onecolumn"
384- i18n:domain="launchpad">
385- <body tal:define="context_menu context/menu:context">
386- <div metal:fill-slot="main">
387- <div metal:use-macro="context/@@launchpad_form/form" />
388- </div>
389- </body>
390-</html>
391
392=== removed file 'lib/lp/translations/templates/translator-remove.pt'
393--- lib/lp/translations/templates/translator-remove.pt 2009-07-17 17:59:07 +0000
394+++ lib/lp/translations/templates/translator-remove.pt 1970-01-01 00:00:00 +0000
395@@ -1,36 +0,0 @@
396-<html
397- xmlns="http://www.w3.org/1999/xhtml"
398- xmlns:tal="http://xml.zope.org/namespaces/tal"
399- xmlns:metal="http://xml.zope.org/namespaces/metal"
400- xmlns:i18n="http://xml.zope.org/namespaces/i18n"
401- xml:lang="en"
402- lang="en"
403- dir="ltr"
404- metal:use-macro="view/macro:page/onecolumn"
405- i18n:domain="launchpad">
406- <body tal:define="context_menu context/menu:context">
407- <div metal:fill-slot="main">
408- <div>
409- <a href="/+groups">Translation groups:</a>
410- <a tal:attributes="href context/translationgroup/fmt:url">
411- <tal:translation-group replace="context/translationgroup/title">
412- Foo bar
413- </tal:translation-group> translation group
414- </a>
415- </div>
416- <h1>
417- Remove
418- <tal:translator replace="context/translator/fmt:displayname">
419- Carlos
420- </tal:translator> as the
421- <tal:language replace="context/language/englishname">
422- Spanish
423- </tal:language> translator
424- </h1>
425-
426- <h2>Are you sure you want to remove this translator?</h2>
427-
428- <div metal:use-macro="context/@@launchpad_form/form" />
429- </div>
430- </body>
431-</html>
432