Merge lp:~sinzui/launchpad/base-layout-bug-407052 into lp:launchpad
- base-layout-bug-407052
- Merge into devel
Status: | Merged |
---|---|
Merged at revision: | not available |
Proposed branch: | lp:~sinzui/launchpad/base-layout-bug-407052 |
Merge into: | lp:launchpad |
Diff against target: | None lines |
To merge this branch: | bzr merge lp:~sinzui/launchpad/base-layout-bug-407052 |
Related bugs: |
Reviewer | Review Type | Date Requested | Status |
---|---|---|---|
Abel Deuring (community) | Approve | ||
Review via email: mp+9492@code.launchpad.net |
Commit message
Description of the change
Curtis Hovey (sinzui) wrote : | # |
Abel Deuring (adeuring) wrote : | # |
Hi Curtis,
A nice branch; thanks for the detailed cover letter!
I have only a few cosmetic remarks, see below.
> === added file 'lib/lp/
> --- lib/lp/
> +++ lib/lp/
> @@ -0,0 +1,114 @@
> +======
> +NavigationMenu views
> +======
> +
> +Navigation menus are used to create links to related pages. The menus
> +are usually bound to a view.
> +
> + >>> from zope.component import provideAdapter
> + >>> from zope.interface import implements, Interface
> + >>> from canonical.
> + >>> from canonical.
> + ... enabled_
> + >>> from canonical.
> + >>> from canonical.
> +
> + >>> class IEditMenuMarker
> + ... """A marker for a menu and a view."""
> +
> + >>> class EditMenu(
> + ... """A simple menu."""
> + ... usedfor = IEditMenuMarker
> + ... facet = 'overview'
> + ... title = 'Related pages'
> + ... links = ('edit_thing', 'edit_people', 'admin')
> + ...
> + ... def edit_thing(self):
> + ... return Link('+edit', 'Edit thing', icon='edit')
> + ...
> + ... def edit_people(self):
> + ... return Link('+
> + ...
> + ... @enabled_
> + ... def admin(self):
> + ... return Link('+admin', 'Administer this user')
> +
> + >>> class EditView(
> + ... """A simple view."""
> + ... implements(
> + ... # A hack that reveals secret of how facet work.
> + ... __launchpad_
> +
> + # Menu's are normally registered using the menu ZCML directive.
s/Menu's/Menus/
> + >>> provideAdapter(
> + ... EditMenu, [IEditMenuMarker], INavigationMenu, name="overview")
> +
> +The related pages portlet is rendered using a TALES call passing the view
> +to the named adapter: <tal:menu replace="structure view/@@
> +
> + >>> user = factory.
> + >>> view = EditView(user, LaunchpadTestRe
> + >>> menu_view = create_
> + ... view, '+related-pages', principal=user)
> + >>> print menu_view.
> + /.../navigation
> +
> +The view provides access the menu's title and links. The both enabled
> +and disabled links are included.
s/The both/Both the/
> +
> + >>> print menu_view.title
> + Related pages
> + >>> for link in menu_view.links:
> + ... print link.enabled, link.url
> + True http://
> + True http://
> + False http://
> +
> +The view renders the a heading using the menu title and a list of the
> +enabled and linked links. The template uses t...
Curtis Hovey (sinzui) wrote : | # |
Thanks for the review Abel.
On Fri, 2009-07-31 at 11:33 +0000, Abel Deuring wrote:
> Review: Approve
> Hi Curtis,
>
> A nice branch; thanks for the detailed cover letter!
>
> I have only a few cosmetic remarks, see below.
>
>
> > === added file 'lib/lp/
> > --- lib/lp/
> > +++ lib/lp/
...
> > + >>> class EditView(
> > + ... """A simple view."""
> > + ... implements(
> > + ... # A hack that reveals secret of how facet work.
Fixed facet, should be factets
> > + ... __launchpad_
> > +
> > + # Menu's are normally registered using the menu ZCML directive.
>
> s/Menu's/Menus/
fixed
> > + >>> provideAdapter(
> > + ... EditMenu, [IEditMenuMarker], INavigationMenu, name="overview")
> > +
> > +The related pages portlet is rendered using a TALES call passing the view
> > +to the named adapter: <tal:menu replace="structure view/@@
> > +
> > + >>> user = factory.
> > + >>> view = EditView(user, LaunchpadTestRe
> > + >>> menu_view = create_
> > + ... view, '+related-pages', principal=user)
> > + >>> print menu_view.
> > + /.../navigation
> > +
> > +The view provides access the menu's title and links. The both enabled
> > +and disabled links are included.
>
> s/The both/Both the/
Fixed
> > +
> > + >>> print menu_view.title
> > + Related pages
> > + >>> for link in menu_view.links:
> > + ... print link.enabled, link.url
> > + True http://
> > + True http://
> > + False http://
> > +
> > +The view renders the a heading using the menu title and a list of the
> > +enabled and linked links. The template uses the inline-link rules, if the
> > +link has a icon, the classes are set, otherwise a style attribute is used.
>
> s/renders the a/renders the/
> s/a icon/an icon/
>
> "linked links" sounds a bit odd to me ;) What about "list of enabled links"?
The links `enabled` and `linked` properties should not be confused. The
former is about permission, the later is about relevance.
This is the diff of my changes:
=== modified file 'lib/lp/
--- lib/lp/
+++ lib/lp/
@@ -36,10 +36,10 @@
>>> class EditView(
... """A simple view."""
... implements(
- ... # A hack that reveals secret of how facet work.
+ ... # A hack that reveals secret of how facets work.
... __launchpad_
- # Menu's are normally registered using the menu ZCML directive.
+ # Menus are normally registered using the menu ZCML directive.
>>> provideAdapter(
... EditMenu, [IEditMenuMarker], INavigationMenu, name="overview")
@@ -53,7 +53,7 @@
>>> print menu_view.
Preview Diff
1 | === modified file 'lib/lp/app/browser/configure.zcml' |
2 | --- lib/lp/app/browser/configure.zcml 2009-07-17 02:25:09 +0000 |
3 | +++ lib/lp/app/browser/configure.zcml 2009-07-31 02:42:44 +0000 |
4 | @@ -14,4 +14,11 @@ |
5 | template="../templates/base-layout-macros.pt" |
6 | permission="zope.Public" |
7 | /> |
8 | + <browser:page |
9 | + for="*" |
10 | + name="+related-pages" |
11 | + class="canonical.launchpad.browser.launchpad.NavigationMenuTabs" |
12 | + template="../templates/navigationmenu-related-pages.pt" |
13 | + permission="zope.Public" |
14 | + /> |
15 | </configure> |
16 | |
17 | === modified file 'lib/lp/app/browser/tests/base-layout.txt' |
18 | --- lib/lp/app/browser/tests/base-layout.txt 2009-07-27 20:57:01 +0000 |
19 | +++ lib/lp/app/browser/tests/base-layout.txt 2009-07-30 20:38:50 +0000 |
20 | @@ -237,7 +237,8 @@ |
21 | >>> print content.h1 |
22 | <h1>Heading</h1> |
23 | |
24 | -The page heading slot's default behaviour is to use the context.title. |
25 | +The page heading slot's default behaviour is to use the context.title and |
26 | +place it in a <h1>. |
27 | |
28 | >>> class DefaultHeadingView(LaunchpadView): |
29 | ... """A simple view to test base-layout.""" |
30 | |
31 | === added file 'lib/lp/app/browser/tests/menu.txt' |
32 | --- lib/lp/app/browser/tests/menu.txt 1970-01-01 00:00:00 +0000 |
33 | +++ lib/lp/app/browser/tests/menu.txt 2009-07-31 02:42:44 +0000 |
34 | @@ -0,0 +1,114 @@ |
35 | +==================== |
36 | +NavigationMenu views |
37 | +==================== |
38 | + |
39 | +Navigation menus are used to create links to related pages. The menus |
40 | +are usually bound to a view. |
41 | + |
42 | + >>> from zope.component import provideAdapter |
43 | + >>> from zope.interface import implements, Interface |
44 | + >>> from canonical.launchpad.webapp.interfaces import INavigationMenu |
45 | + >>> from canonical.launchpad.webapp.menu import ( |
46 | + ... enabled_with_permission, Link, NavigationMenu) |
47 | + >>> from canonical.launchpad.webapp.publisher import LaunchpadView |
48 | + >>> from canonical.launchpad.webapp.servers import LaunchpadTestRequest |
49 | + |
50 | + >>> class IEditMenuMarker(Interface): |
51 | + ... """A marker for a menu and a view.""" |
52 | + |
53 | + >>> class EditMenu(NavigationMenu): |
54 | + ... """A simple menu.""" |
55 | + ... usedfor = IEditMenuMarker |
56 | + ... facet = 'overview' |
57 | + ... title = 'Related pages' |
58 | + ... links = ('edit_thing', 'edit_people', 'admin') |
59 | + ... |
60 | + ... def edit_thing(self): |
61 | + ... return Link('+edit', 'Edit thing', icon='edit') |
62 | + ... |
63 | + ... def edit_people(self): |
64 | + ... return Link('+edit-people', 'Edit people related to thing') |
65 | + ... |
66 | + ... @enabled_with_permission('launchpad.Admin') |
67 | + ... def admin(self): |
68 | + ... return Link('+admin', 'Administer this user') |
69 | + |
70 | + >>> class EditView(LaunchpadView): |
71 | + ... """A simple view.""" |
72 | + ... implements(IEditMenuMarker) |
73 | + ... # A hack that reveals secret of how facet work. |
74 | + ... __launchpad_facetname__ = 'overview' |
75 | + |
76 | + # Menu's are normally registered using the menu ZCML directive. |
77 | + >>> provideAdapter( |
78 | + ... EditMenu, [IEditMenuMarker], INavigationMenu, name="overview") |
79 | + |
80 | +The related pages portlet is rendered using a TALES call passing the view |
81 | +to the named adapter: <tal:menu replace="structure view/@@+related-pages" /> |
82 | + |
83 | + >>> user = factory.makePerson(name='beaker') |
84 | + >>> view = EditView(user, LaunchpadTestRequest()) |
85 | + >>> menu_view = create_initialized_view( |
86 | + ... view, '+related-pages', principal=user) |
87 | + >>> print menu_view.template.filename |
88 | + /.../navigationmenu-related-pages.pt |
89 | + |
90 | +The view provides access the menu's title and links. The both enabled |
91 | +and disabled links are included. |
92 | + |
93 | + >>> print menu_view.title |
94 | + Related pages |
95 | + >>> for link in menu_view.links: |
96 | + ... print link.enabled, link.url |
97 | + True http://launchpad.dev/~beaker/+edit |
98 | + True http://launchpad.dev/~beaker/+edit-people |
99 | + False http://launchpad.dev/~beaker/+admin |
100 | + |
101 | +The view renders the a heading using the menu title and a list of the |
102 | +enabled and linked links. The template uses the inline-link rules, if the |
103 | +link has a icon, the classes are set, otherwise a style attribute is used. |
104 | + |
105 | + >>> print menu_view.render() |
106 | + <div id="related-pages" class="portlet"> |
107 | + <h2>Related pages</h2> |
108 | + <ul> |
109 | + <li> |
110 | + <a href="..." |
111 | + class="menu-link-edit_thing sprite modify edit">Edit thing</a> |
112 | + </li> |
113 | + <li> |
114 | + <a style="..." href="..." |
115 | + class="menu-link-edit_people">Edit people related to thing</a> |
116 | + </li> |
117 | + </ul> |
118 | + </div> |
119 | + |
120 | +The link is not displayed if the link matches the requested URL (not linked). |
121 | +The page will not render a link to itself. |
122 | + |
123 | + >>> request = LaunchpadTestRequest( |
124 | + ... SERVER_URL='http://launchpad.dev/~beaker/+edit') |
125 | + >>> print request.getURL() |
126 | + http://launchpad.dev/~beaker/+edit |
127 | + |
128 | + >>> view = EditView(user, request) |
129 | + >>> menu_view = create_initialized_view( |
130 | + ... view, '+related-pages', principal=user) |
131 | + >>> for link in menu_view.links: |
132 | + ... print link.enabled, link.linked, link.url |
133 | + True False http://launchpad.dev/~beaker/+edit |
134 | + True True http://launchpad.dev/~beaker/+edit-people |
135 | + False True http://launchpad.dev/~beaker/+admin |
136 | + |
137 | + >>> print menu_view.render() |
138 | + <div id="related-pages" class="portlet"> |
139 | + <h2>Related pages</h2> |
140 | + <ul> |
141 | + <li> |
142 | + <a style="..." href="..." |
143 | + class="menu-link-edit_people">Edit people related to thing</a> |
144 | + </li> |
145 | + </ul> |
146 | + </div> |
147 | + |
148 | + |
149 | |
150 | === modified file 'lib/lp/app/browser/tests/testfiles/main-only.pt' |
151 | --- lib/lp/app/browser/tests/testfiles/main-only.pt 2009-07-24 04:26:14 +0000 |
152 | +++ lib/lp/app/browser/tests/testfiles/main-only.pt 2009-07-30 20:38:50 +0000 |
153 | @@ -12,7 +12,7 @@ |
154 | </head> |
155 | |
156 | <body> |
157 | - <tal:heading metal:fill-slot="heading">Heading</tal:heading> |
158 | + <tal:heading metal:fill-slot="heading"><h1>Heading</h1></tal:heading> |
159 | <tal:main metal:fill-slot="main"> |
160 | <div class="top-portlet"> |
161 | <p class="registered"> |
162 | |
163 | === modified file 'lib/lp/app/browser/tests/testfiles/main-side.pt' |
164 | --- lib/lp/app/browser/tests/testfiles/main-side.pt 2009-07-24 04:26:14 +0000 |
165 | +++ lib/lp/app/browser/tests/testfiles/main-side.pt 2009-07-30 20:38:50 +0000 |
166 | @@ -12,7 +12,7 @@ |
167 | </head> |
168 | |
169 | <body> |
170 | - <tal:heading metal:fill-slot="heading">Heading</tal:heading> |
171 | + <tal:heading metal:fill-slot="heading"><h1>Heading</h1></tal:heading> |
172 | <tal:main metal:fill-slot="main"> |
173 | <div class="top-portlet"> |
174 | <p class="registered"> |
175 | |
176 | === modified file 'lib/lp/app/browser/tests/testfiles/searchless.pt' |
177 | --- lib/lp/app/browser/tests/testfiles/searchless.pt 2009-07-24 04:26:14 +0000 |
178 | +++ lib/lp/app/browser/tests/testfiles/searchless.pt 2009-07-30 20:38:50 +0000 |
179 | @@ -12,7 +12,7 @@ |
180 | </head> |
181 | |
182 | <body> |
183 | - <tal:heading metal:fill-slot="heading">Heading</tal:heading> |
184 | + <tal:heading metal:fill-slot="heading"><h1>Heading</h1></tal:heading> |
185 | <tal:main metal:fill-slot="main"> |
186 | <div class="top-portlet"> |
187 | <p class="registered"> |
188 | |
189 | === modified file 'lib/lp/app/templates/base-layout.pt' |
190 | --- lib/lp/app/templates/base-layout.pt 2009-07-27 20:57:01 +0000 |
191 | +++ lib/lp/app/templates/base-layout.pt 2009-07-30 20:38:50 +0000 |
192 | @@ -137,10 +137,10 @@ |
193 | xml:lang view/lang|default_language|default; |
194 | dir view/dir|string:ltr"> |
195 | <tal:location condition="view/macro:pagehas/applicationtabs"> |
196 | - <h1><tal:heading |
197 | + <h1 |
198 | tal:condition="context/title|nothing" |
199 | tal:content="context/title" |
200 | - metal:define-slot="heading" /></h1> |
201 | + metal:define-slot="heading" /> |
202 | <tal:breadcrumbs> |
203 | <!-- future breadcrumb rule --> |
204 | </tal:breadcrumbs> |
205 | |
206 | === added file 'lib/lp/app/templates/navigationmenu-related-pages.pt' |
207 | --- lib/lp/app/templates/navigationmenu-related-pages.pt 1970-01-01 00:00:00 +0000 |
208 | +++ lib/lp/app/templates/navigationmenu-related-pages.pt 2009-07-31 02:42:44 +0000 |
209 | @@ -0,0 +1,16 @@ |
210 | +<div |
211 | + xmlns:tal="http://xml.zope.org/namespaces/tal" |
212 | + xmlns:i18n="http://xml.zope.org/namespaces/i18n" |
213 | + id="related-pages" class="portlet"> |
214 | + <h2 tal:content="view/title">Menu title</h2> |
215 | + |
216 | + <ul> |
217 | + <tal:link tal:repeat="link view/links"> |
218 | + <tal:enabled tal:condition="link/enabled"> |
219 | + <li tal:condition="link/linked"> |
220 | + <a tal:replace="structure link/fmt:icon-link" /> |
221 | + </li> |
222 | + </tal:enabled> |
223 | + </tal:link> |
224 | + </ul> |
225 | +</div> |
226 |
This is my branch to address two base-layout issues.
lp:~sinzui/launchpad/base-layout-bug-407052 /bugs.launchpad .net/bugs/ 407052 /bugs.launchpad .net/bugs/ 407055 .*/(base- layout| menu)" implementation: no one.
Diff size: 226
Launchpad bug: https:/
https:/
Test command: ./bin/test -vvt "lp/app/
Pre-
Target release: 2.2.8
= Two base-layout issues =
Bug #407052 base-layout heading slot breaks the title edit widget
The title edit widget creates it's own <h1> with an id and class. When
used with the heading slot a <h1> is generated inside the <h1>.
The solution is that the <h1> only be created when base-layout is
automatically creating a title for the context object.
Bug #407055 NavigationMenu is still needed but not supported by base-layout
While working on the project edit pages in an experiment to move
them to the 3.0 layout. I realised I had dismantled the edit
NavigationMenu, then added a section to the page that had the same
links. We should be reusing the navigation menus
Since many pages need to have a releated pages section with a list
of links, there should be a view that can be called to make the
standard markup. This will enforce consistency, reduce the amount of
typing, and allow us to *not* remove the NavigationMenu from views.
== Rules ==
Bug #407052 base-layout heading slot breaks the title edit widget
Make the template pass the <h1> to the slot. If the slot is not
called by the template, base-layout makes a <h1> using the
context.title
Bug #407055 NavigationMenu is still needed but not supported by base-layout
There is already a view for the NavigationMenu. We need a new
template that renders the portlet, heading, and list. This structure
is the same as the one used on series and milestones now.
== QA ==
Bug #407052 base-layout heading slot breaks the title edit widget
No page has encountered this yet on edge staging. This fix can only
verified by a page in development (namely the product-index.pt) that
I am working on.
Bug #407055 NavigationMenu is still needed but not supported by base-layout
No page uses this yet, but I have branch that does.
== Lint ==
Checking for conflicts. and issues in doctests and templates.
Running jslint, xmllint, pyflakes, and pylint.
Using normal rules.
Linting changed files: app/browser/ configure. zcml app/browser/ tests/base- layout. txt app/browser/ tests/menu. txt app/browser/ tests/testfiles /main-only. pt app/browser/ tests/testfiles /main-side. pt app/browser/ tests/testfiles /searchless. pt app/templates/ base-layout. pt app/templates/ navigationmenu- related- pages.pt
lib/lp/
lib/lp/
lib/lp/
lib/lp/
lib/lp/
lib/lp/
lib/lp/
lib/lp/
== Test ==
* lib/lp/ app/browser/ tests/menu. txt app/browser/ tests/base- layout. txt app/browser/ tests/testfiles /main-only. pt app/browser/ tests/testfiles /main-side. pt app/browser/ tests/testfiles /search. ..
* Created a test to verify the behaviour of the related pages template.
* lib/lp/
* I Updated the narative to explain that the <h1> must be passed by
the callsite.
* lib/lp/
* lib/lp/
* lib/lp/