1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
|
= RenamedView =
As Launchpad is reorganized, views are renamed. It is usually advisable
to leave a permanent redirect from the old name to the new name. This
allows search engines and bookmark to update transparently from the old
name to the new one.
For this case, we have a RenamedView that will take care of the
redirection.
>>> from lp.services.webapp.publisher import RenamedView
>>> from lp.services.webapp.servers import LaunchpadTestRequest
Let's say we rename the '+old_tickets_page' view on IQuestionTarget to
'+questions'. A RenamedView redirecting to the new name would be created
like this:
>>> request = LaunchpadTestRequest()
>>> from lp.registry.interfaces.distribution import IDistributionSet
>>> ubuntu = getUtility(IDistributionSet).getByName('ubuntu')
>>> view = RenamedView(ubuntu, request, '+questions')
(Note that the RenamedView class doesn't need to be aware of the
previous name. The old name will be hooked up with the RenamedView
via ZCML.)
When the view is called, it redirects to the same context but with
the new name. The redirection status is 301 (Moved permently) which
will make search engines discards the old URLs and some browser to
update bookmarks.
>>> view()
u''
>>> request.response.getStatus()
301
>>> print request.response.getHeader('Location')
http://launchpad.dev/ubuntu/+questions
The view can also work for names registered on the root, and the
new_name can be a relative path.
>>> from lp.services.webapp.interfaces import ILaunchpadRoot
>>> root = getUtility(ILaunchpadRoot)
>>> view = RenamedView(root, LaunchpadTestRequest(), '+tour/index.html')
>>> view()
u''
>>> request.response.getStatus()
301
>>> print view.request.response.getHeader('Location')
http://launchpad.dev/+tour/index.html
== Handling GET parameters ==
If there was any query parameters on the request, they are appended
to the redirected URL.
>>> request = LaunchpadTestRequest(
... QUERY_STRING='field.status=Open')
>>> view = RenamedView(ubuntu, request, '+questions')
>>> view()
u''
>>> print request.response.getHeader('Location')
http://launchpad.dev/ubuntu/+questions?field.status=Open
== Redirecting to another virtual host ==
The view also takes an optional 'rootsite' parameter, which will
change the virtual host used for the redirection.
>>> request = LaunchpadTestRequest()
>>> view = RenamedView(
... ubuntu, request, '+questions', rootsite='answers')
>>> view()
u''
>>> print request.response.getHeader('Location')
http://answers.launchpad.dev/ubuntu/+questions
== Traversal errors ==
If an object cannot be found during traversal, RenamedView will raise
a NotFound error. For example, requesting a non-existent question will
raise an error. e.g. http://launchpad.dev/ubuntu/+tickets/foo
>>> request = LaunchpadTestRequest()
>>> view = RenamedView(ubuntu, request, '+tickets')
>>> view.publishTraverse(request, u'foo')
Traceback (most recent call last):
...
NotFound: Object: <Distribution 'Ubuntu' (ubuntu)>, name: u'foo'
== Registering from ZCML ==
Finally, it is possible to register RenamedView from ZCML. The
browser:renamed-page is available for this purpose.
>>> from zope.configuration import xmlconfig
>>> zcmlcontext = xmlconfig.string("""
... <configure xmlns:browser="http://namespaces.zope.org/browser">
... <include package="lp.services.webapp" file="meta.zcml" />
... <include package="zope.app.zcmlfiles" file="meta.zcml" />
... <browser:renamed-page
... for="lp.answers.interfaces.questiontarget.IQuestionTarget"
... name="+old_tickets_page"
... new_name="+questions"
... rootsite="answers"
... />
... </configure>
... """)
>>> from zope.component import getMultiAdapter
>>> request = LaunchpadTestRequest()
>>> view = getMultiAdapter((ubuntu, request), name='+old_tickets_page')
>>> view()
u''
>>> print request.response.getHeader('Location')
http://answers.launchpad.dev/ubuntu/+questions
|