Merge lp:~sinzui/launchpad/action-menu-bug-403641 into lp:launchpad

Proposed by Curtis Hovey
Status: Merged
Merged at revision: not available
Proposed branch: lp:~sinzui/launchpad/action-menu-bug-403641
Merge into: lp:launchpad
Diff against target: None lines
To merge this branch: bzr merge lp:~sinzui/launchpad/action-menu-bug-403641
Reviewer Review Type Date Requested Status
Paul Hummer (community) Approve
Review via email: mp+9793@code.launchpad.net
To post a comment you must log in.
Revision history for this message
Curtis Hovey (sinzui) wrote :
Download full text (5.1 KiB)

This is my branch to add support for an action menu and involvement portlet.
This branch is extracted form my product index page branch.

    lp:~sinzui/launchpad/action-menu-bug-403641
    Diff size: 496
    Launchpad bug: https://bugs.launchpad.net/bugs/403641
                   https://bugs.launchpad.net/bugs/403651
    Test command: ./bin/test -vvt "(tales|menu|pillar-views).txt"
    Pre-implementation: beuno
    Target release: 2.2.8

= Add support for an action menu and involvement portlet =

Bug 403641 [base-layout must support a object action menu]
    The 3.0 design allows an object to have an action menu for links
    that affect the object that cannot be represented in the content.
    The examples links are "Change details", "Change password", and
    "Make private".

Bug 403651 [base-layout must support an Involvement menu]
    The 3.0 design has an involvement portlet to encourage users to
    participate.

Martin asked me to remove the 2.0 backward compatibility style hacks
and land it as soon as possible so that the engineers designing pages
see their work appear as the example designs.

== Rules ==

Bug 403641 [base-layout must support a object action menu]
    Reuse the NavigationMenu to present the menu. The nav menu is
    best because it can be used with with context object and views
    (which may be necessary)

Bug 403651 [base-layout must support an Involvement menu]
    Create a view to render the involvement menu for pillars. The
    menu should only list the officially supported applications.

== QA ==

Bug 403641 [base-layout must support a object action menu]
    Nothing uses this on edge/staging. It works with the product-page
    branch. We can get feedback from engineers who want to use this
    now.

Bug 403651 [base-layout must support an Involvement menu]
    Nothing uses this on edge/staging. It works with the product-page
    branch. We can get feedback from engineers who want to use this
    now.

As for the style changes, the search page will have smaller fonts.
Developers will stop complaining that the fonts looks to big and the
space is wrong.

== Lint ==

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

Linting changed files:
  lib/canonical/launchpad/browser/launchpad.py
  lib/canonical/launchpad/doc/tales.txt
  lib/canonical/launchpad/icing/style-3-0.css
  lib/canonical/launchpad/images/answers-arrow-right.png
  lib/canonical/launchpad/images/bg-project-downloads.png
  lib/canonical/launchpad/images/blueprints-arrow-right.png
  lib/canonical/launchpad/images/bugs-arrow-right.png
  lib/canonical/launchpad/images/code-arrow-right.png
  lib/canonical/launchpad/images/link-grey-arrow.png
  lib/canonical/launchpad/images/translations-arrow-right.png
  lib/canonical/launchpad/webapp/tales.py
  lib/lp/app/browser/configure.zcml
  lib/lp/app/browser/tests/menu.txt
  lib/lp/app/templates/navigationmenu-actions.pt
  lib/lp/registry/browser/configure.zcml
  lib/lp/registry/browser/pillar.py
  lib/lp/registry/browser/tests/pillar-views.txt
  lib/lp/registry/templates/pillar-involvement-portlet.pt

== Test ==

    * lib/canoni...

Read more...

Revision history for this message
Paul Hummer (rockstar) :
review: Approve

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
=== modified file 'lib/canonical/launchpad/browser/launchpad.py'
--- lib/canonical/launchpad/browser/launchpad.py 2009-07-29 00:30:50 +0000
+++ lib/canonical/launchpad/browser/launchpad.py 2009-08-06 14:09:56 +0000
@@ -173,6 +173,7 @@
173 menu = queryAdapter(self.context, INavigationMenu, name=facet)173 menu = queryAdapter(self.context, INavigationMenu, name=facet)
174 if menu is not None:174 if menu is not None:
175 self.title = menu.title175 self.title = menu.title
176 self.enabled_links = [link for link in self.links if link.enabled]
176177
177 def render(self):178 def render(self):
178 if not self.links:179 if not self.links:
179180
=== modified file 'lib/canonical/launchpad/doc/tales.txt'
--- lib/canonical/launchpad/doc/tales.txt 2009-08-05 19:34:07 +0000
+++ lib/canonical/launchpad/doc/tales.txt 2009-08-06 15:14:54 +0000
@@ -481,6 +481,11 @@
481 http://.../+download/test.txt: test file (4 bytes)481 http://.../+download/test.txt: test file (4 bytes)
482 http://.../+download/test.txt/+md5:482 http://.../+download/test.txt/+md5:
483483
484The url for the release file can be retrieved using fmt:url.
485
486 >>> print test_tales("release_file/fmt:url", release_file=release_file)
487 http://launchpad.dev/.../+download/test.txt
488
484489
485=== Product series ===490=== Product series ===
486491
487492
=== modified file 'lib/canonical/launchpad/icing/style-3-0.css'
--- lib/canonical/launchpad/icing/style-3-0.css 2009-08-05 19:34:07 +0000
+++ lib/canonical/launchpad/icing/style-3-0.css 2009-08-06 15:02:25 +0000
@@ -183,7 +183,7 @@
183183
184/* Page layout */184/* Page layout */
185.yui-d0 {185.yui-d0 {
186 margin: 10px 20px; /* 20px sides are 2.0 backward compatability */186 margin: 10px 20px;
187 }187 }
188.yui-t4 .yui-b {188.yui-t4 .yui-b {
189 width: 21%;189 width: 21%;
@@ -199,6 +199,7 @@
199 padding-top: 0.5em;199 padding-top: 0.5em;
200 }200 }
201.portlet, .aside {201.portlet, .aside {
202 clear: both;
202 border-top: 1px solid #d6d6d6;203 border-top: 1px solid #d6d6d6;
203 padding: 0.5em 0;204 padding: 0.5em 0;
204 }205 }
@@ -236,7 +237,8 @@
236/* Default text presentation */237/* Default text presentation */
237html, body {238html, body {
238 font-family: bitstream vera sans, arial, helvetica, clean, sans-serif;239 font-family: bitstream vera sans, arial, helvetica, clean, sans-serif;
239 font-size: 97%; /* 2.0 backward compatability */240 font-family: sans-serif;
241 font-size: 93%;
240 }242 }
241body.private {243body.private {
242 /* It must be obvious to the user that the context is private */244 /* It must be obvious to the user that the context is private */
@@ -246,7 +248,6 @@
246 clear: none;248 clear: none;
247 padding-top: 6px; /* An offset from the logo. */249 padding-top: 6px; /* An offset from the logo. */
248 font-size: 197%;250 font-size: 197%;
249 margin-bottom: 0.5em; /* 2.0 backward compatability */
250 }251 }
251h2 {252h2 {
252 margin-bottom: 0.3em;253 margin-bottom: 0.3em;
@@ -270,7 +271,10 @@
270 list-style: decimal outside;271 list-style: decimal outside;
271 }272 }
272li {273li {
273 padding-bottom: .2em;274 padding-bottom: .3em;
275 }
276dt {
277 margin-bottom: .1em;
274 }278 }
275dd {279dd {
276 margin-bottom: .8em;280 margin-bottom: .8em;
@@ -305,13 +309,13 @@
305 }309 }
306.see-all a {310.see-all a {
307 padding-left: 8px;311 padding-left: 8px;
308 background: url(../images/link-grey-arrow.gif) left center no-repeat;312 background: url(/@@/link-grey-arrow.gif) left center no-repeat;
309 font-size: 72%;313 font-size: 72%;
310 color: #484848;314 color: #484848;
311 text-decoration: underline;315 text-decoration: underline;
312 }316 }
313.rss-right {317.rss-right {
314 background: url(https://launchpad.net/@@/rss.png) right center no-repeat;318 background: url(/@@/rss.png) right center no-repeat;
315 }319 }
316.logo {320.logo {
317 float: left;321 float: left;
@@ -321,7 +325,6 @@
321 margin: 0 5px 0 0;325 margin: 0 5px 0 0;
322 }326 }
323.registered {327.registered {
324 margin-top: -0.5em; /* 2.0 backward compatability */
325 font-size: 85%;328 font-size: 85%;
326 color: #666;329 color: #666;
327 font-style: italic;330 font-style: italic;
@@ -330,15 +333,23 @@
330 clear: both;333 clear: both;
331 font-size: 100%;334 font-size: 100%;
332 }335 }
336.summary {
337 margin: 0 0 1em 0;
338 font-size: 138.5%;
339 }
340
333341
334/* Common list presentations. */342/* Common list presentations. */
335.bulleted {343.bulleted {
336 margin-bottom: 0.5em;344 margin-bottom: 0.5em;
337 }345 }
338.bulleted li {346.bulleted li {
339 margin: auto auto 0.2em 2em;347 margin: 0 0 0 2em;
340 list-style-type: disc;348 list-style-type: disc;
341 }349 }
350.horizontal {
351 margin: 1em 0 0 0;
352 }
342.horizontal li {353.horizontal li {
343 display: inline;354 display: inline;
344 padding: 0 1.5em 0 0;355 padding: 0 1.5em 0 0;
@@ -444,15 +455,13 @@
444 background: #fbfbfb;455 background: #fbfbfb;
445 }456 }
446457
447.downloads {
448 font-weight: bold;
449 }
450.downloads a {458.downloads a {
451 color: #4f843c;459 color: #4f843c;
452 }460 }
453.downloads li {461.downloads li {
454 margin: 0;462 margin: 0;
455 padding: 2px 0 0;463 padding: 2px 0 0;
464 font-weight: bold;
456 }465 }
457.downloads li a {466.downloads li a {
458 display: block;467 display: block;
@@ -461,18 +470,26 @@
461 -moz-border-radius: 1.5%;470 -moz-border-radius: 1.5%;
462 -webkit-border-radius: 1.5%;471 -webkit-border-radius: 1.5%;
463 border-radius: 1.5%;472 border-radius: 1.5%;
464 background: #4f843c url(../images/bg-project-downloads.gif) center right no-repeat;473 background: #4f843c url(/@@/bg-project-downloads.png) center right no-repeat;
465 padding: 6%;474 padding: 6%;
475 padding-right: 50px;
466 color: #fff;476 color: #fff;
467 font-size: 108%;477 font-size: 108%;
468 text-decoration: underline;478 text-decoration: underline;
469 }479 }
470.downloads .released {480.downloads .released {
471 margin: 0 0 0.5em 0;481 margin: .3em 0 1em 0;
472 background: #f3f3f3 url(../images/bg-project-released.gif) right bottom no-repeat;482 padding: 0 .2em 0 0;
473 padding: 0.4em 0.2em;483 text-align: right;
474 font-size: 85%;484 }
475 font-weight: normal;485.downloads .released span {
486 -moz-border-radius: 0 0 3% 3%;
487 -webkit-border-radius: 0 0 5% 5%;
488 border-radius: 0 0 3% 3%;
489 background: #d3e3c7;
490 padding: 0.2em 1em;
491 }
492.downloads .alternate {
476 text-align: right;493 text-align: right;
477 }494 }
478495
@@ -491,27 +508,26 @@
491 }508 }
492.involvement a.bugs {509.involvement a.bugs {
493 color: #b9413e;510 color: #b9413e;
494 background: url(../images/red-arrow.gif) right center no-repeat;511 background: url(/@@/bugs-arrow-right.png) right center no-repeat;
495 }512 }
496.involvement a.question {513.involvement a.question {
497 color: #5265b2;514 color: #5265b2;
498 background: url(../images/blue-arrow.gif) right center no-repeat;515 background: url(/@@/answers-arrow-right.png) right center no-repeat;
499 }516 }
500.involvement a.translate {517.involvement a.translate {
501 color: #c5458e;518 color: #c5458e;
502 background: url(../images/pink-arrow.gif) right center no-repeat;519 background: url(/@@/translations-arrow-right.png) right center no-repeat;
503 }520 }
504.involvement a.code {521.involvement a.code {
505 color: #d39f57;522 color: #d39f57;
506 background: url(../images/yellow-arrow.gif) right center no-repeat;523 background: url(/@@/images/code-arrow-right.png) right center no-repeat;
507 }524 }
508.involvement a.blueprint {525.involvement a.blueprint {
509 color: #5ba4c6;526 color: #5ba4c6;
510 background: url(../images/lightblue-arrow.gif) right center no-repeat;527 background: url(/@@/images/blueprints-arrow-right.png) right center no-repeat;
511 }528 }
512529
513.announcements li {530.announcements li {
514 font-size: 85%;
515 margin-bottom: 0.5em;531 margin-bottom: 0.5em;
516 }532 }
517.announcements li strong,533.announcements li strong,
@@ -525,14 +541,6 @@
525 border-bottom: 1px solid #d0d0d0;541 border-bottom: 1px solid #d0d0d0;
526 }542 }
527543
528
529/* Should not be needed with real data */
530.timeline {
531 width: 100%;
532 color: #484848;
533 background: #f7f7f7;
534 }
535
536/* From nice_pre in tales.py */544/* From nice_pre in tales.py */
537pre.wrap {545pre.wrap {
538 white-space: -moz-pre-wrap;546 white-space: -moz-pre-wrap;
@@ -540,3 +548,4 @@
540 white-space: pre-wrap;548 white-space: pre-wrap;
541 word-wrap: break-word;549 word-wrap: break-word;
542}550}
551
543552
=== added file 'lib/canonical/launchpad/images/answers-arrow-right.png'
544Binary files lib/canonical/launchpad/images/answers-arrow-right.png 1970-01-01 00:00:00 +0000 and lib/canonical/launchpad/images/answers-arrow-right.png 2009-08-06 14:09:56 +0000 differ553Binary files lib/canonical/launchpad/images/answers-arrow-right.png 1970-01-01 00:00:00 +0000 and lib/canonical/launchpad/images/answers-arrow-right.png 2009-08-06 14:09:56 +0000 differ
=== added file 'lib/canonical/launchpad/images/bg-project-downloads.png'
545Binary files lib/canonical/launchpad/images/bg-project-downloads.png 1970-01-01 00:00:00 +0000 and lib/canonical/launchpad/images/bg-project-downloads.png 2009-08-06 14:09:56 +0000 differ554Binary files lib/canonical/launchpad/images/bg-project-downloads.png 1970-01-01 00:00:00 +0000 and lib/canonical/launchpad/images/bg-project-downloads.png 2009-08-06 14:09:56 +0000 differ
=== added file 'lib/canonical/launchpad/images/blueprints-arrow-right.png'
546Binary files lib/canonical/launchpad/images/blueprints-arrow-right.png 1970-01-01 00:00:00 +0000 and lib/canonical/launchpad/images/blueprints-arrow-right.png 2009-08-06 14:09:56 +0000 differ555Binary files lib/canonical/launchpad/images/blueprints-arrow-right.png 1970-01-01 00:00:00 +0000 and lib/canonical/launchpad/images/blueprints-arrow-right.png 2009-08-06 14:09:56 +0000 differ
=== added file 'lib/canonical/launchpad/images/bugs-arrow-right.png'
547Binary files lib/canonical/launchpad/images/bugs-arrow-right.png 1970-01-01 00:00:00 +0000 and lib/canonical/launchpad/images/bugs-arrow-right.png 2009-08-06 14:09:56 +0000 differ556Binary files lib/canonical/launchpad/images/bugs-arrow-right.png 1970-01-01 00:00:00 +0000 and lib/canonical/launchpad/images/bugs-arrow-right.png 2009-08-06 14:09:56 +0000 differ
=== added file 'lib/canonical/launchpad/images/code-arrow-right.png'
548Binary files lib/canonical/launchpad/images/code-arrow-right.png 1970-01-01 00:00:00 +0000 and lib/canonical/launchpad/images/code-arrow-right.png 2009-08-06 14:09:56 +0000 differ557Binary files lib/canonical/launchpad/images/code-arrow-right.png 1970-01-01 00:00:00 +0000 and lib/canonical/launchpad/images/code-arrow-right.png 2009-08-06 14:09:56 +0000 differ
=== added file 'lib/canonical/launchpad/images/link-grey-arrow.png'
549Binary files lib/canonical/launchpad/images/link-grey-arrow.png 1970-01-01 00:00:00 +0000 and lib/canonical/launchpad/images/link-grey-arrow.png 2009-08-06 14:09:56 +0000 differ558Binary files lib/canonical/launchpad/images/link-grey-arrow.png 1970-01-01 00:00:00 +0000 and lib/canonical/launchpad/images/link-grey-arrow.png 2009-08-06 14:09:56 +0000 differ
=== added file 'lib/canonical/launchpad/images/translations-arrow-right.png'
550Binary files lib/canonical/launchpad/images/translations-arrow-right.png 1970-01-01 00:00:00 +0000 and lib/canonical/launchpad/images/translations-arrow-right.png 2009-08-06 14:09:56 +0000 differ559Binary files lib/canonical/launchpad/images/translations-arrow-right.png 1970-01-01 00:00:00 +0000 and lib/canonical/launchpad/images/translations-arrow-right.png 2009-08-06 14:09:56 +0000 differ
=== modified file 'lib/canonical/launchpad/webapp/tales.py'
--- lib/canonical/launchpad/webapp/tales.py 2009-08-05 19:34:07 +0000
+++ lib/canonical/launchpad/webapp/tales.py 2009-08-06 14:09:56 +0000
@@ -1190,7 +1190,7 @@
1190class ProductReleaseFileFormatterAPI(ObjectFormatterAPI):1190class ProductReleaseFileFormatterAPI(ObjectFormatterAPI):
1191 """Adapter for `IProductReleaseFile` objects to a formatted string."""1191 """Adapter for `IProductReleaseFile` objects to a formatted string."""
11921192
1193 traversable_names = {'link': 'link'}1193 traversable_names = {'link': 'link', 'url': 'url'}
11941194
1195 def link(self, view_name):1195 def link(self, view_name):
1196 """A hyperlinked ProductReleaseFile.1196 """A hyperlinked ProductReleaseFile.
@@ -1226,6 +1226,10 @@
1226 html += ')'1226 html += ')'
1227 return html % replacements1227 return html % replacements
12281228
1229 def url(self, view_name):
1230 """Return the URL to download the file."""
1231 return self._getDownloadURL(self._context.libraryfile)
1232
1229 @property1233 @property
1230 def _release(self):1234 def _release(self):
1231 return self._context.productrelease1235 return self._context.productrelease
12321236
=== modified file 'lib/lp/app/browser/configure.zcml'
--- lib/lp/app/browser/configure.zcml 2009-07-31 17:14:35 +0000
+++ lib/lp/app/browser/configure.zcml 2009-08-06 14:11:31 +0000
@@ -21,4 +21,11 @@
21 template="../templates/navigationmenu-related-pages.pt"21 template="../templates/navigationmenu-related-pages.pt"
22 permission="zope.Public"22 permission="zope.Public"
23 />23 />
24 <browser:page
25 for="*"
26 name="+global-actions"
27 class="canonical.launchpad.browser.launchpad.NavigationMenuTabs"
28 template="../templates/navigationmenu-actions.pt"
29 permission="zope.Public"
30 />
24</configure>31</configure>
2532
=== modified file 'lib/lp/app/browser/tests/menu.txt'
--- lib/lp/app/browser/tests/menu.txt 2009-07-31 13:25:26 +0000
+++ lib/lp/app/browser/tests/menu.txt 2009-08-06 15:02:25 +0000
@@ -43,6 +43,10 @@
43 >>> provideAdapter(43 >>> provideAdapter(
44 ... EditMenu, [IEditMenuMarker], INavigationMenu, name="overview")44 ... EditMenu, [IEditMenuMarker], INavigationMenu, name="overview")
4545
46
47Related pages
48-------------
49
46The related pages portlet is rendered using a TALES call passing the view50The related pages portlet is rendered using a TALES call passing the view
47to the named adapter: <tal:menu replace="structure view/@@+related-pages" />51to the named adapter: <tal:menu replace="structure view/@@+related-pages" />
4852
@@ -113,3 +117,45 @@
113 </div>117 </div>
114118
115119
120Action menus
121------------
122
123A navigation menu can be presented as an action menu is the side portlets.
124The action menu uses the view's enabled_links property to get the list of
125links.
126
127 >>> menu_view = create_initialized_view(
128 ... view, '+global-actions', principal=user)
129 >>> for link in menu_view.enabled_links:
130 ... print link.enabled, link.linked, link.url
131 True False http://launchpad.dev/~beaker/+edit
132 True True http://launchpad.dev/~beaker/+edit-people
133
134The generated markup is for a portlet with the global-actions id.
135
136 >>> print menu_view.render()
137 <div id="global-actions" class="portlet">
138 <ul>
139 <li>
140 <a href="..."
141 class="menu-link-edit_thing sprite modify edit">Edit thing</a>
142 </li>
143 <li>
144 <a style="..." href="..."
145 class="menu-link-edit_people">Edit people related to thing</a>
146 </li>
147 </ul>
148 </div>
149
150If there are no enabled links, no markup is rendered. For example, a menu
151may contain links that require special privileges to access.
152
153 >>> EditMenu.links = ('admin',)
154
155 >>> menu_view = create_initialized_view(
156 ... view, '+global-actions', principal=user)
157 >>> menu_view.enabled_links
158 []
159
160 >>> print menu_view.render()
161 <BLANKLINE>
116162
=== added file 'lib/lp/app/templates/navigationmenu-actions.pt'
--- lib/lp/app/templates/navigationmenu-actions.pt 1970-01-01 00:00:00 +0000
+++ lib/lp/app/templates/navigationmenu-actions.pt 2009-08-06 14:11:31 +0000
@@ -0,0 +1,11 @@
1<div
2 xmlns:tal="http://xml.zope.org/namespaces/tal"
3 xmlns:i18n="http://xml.zope.org/namespaces/i18n"
4 id="global-actions" class="portlet"
5 tal:condition="view/enabled_links">
6 <ul>
7 <li tal:repeat="link view/enabled_links">
8 <a tal:replace="structure link/fmt:icon-link" />
9 </li>
10 </ul>
11</div>
012
=== modified file 'lib/lp/registry/browser/configure.zcml'
--- lib/lp/registry/browser/configure.zcml 2009-08-03 14:38:55 +0000
+++ lib/lp/registry/browser/configure.zcml 2009-08-06 18:17:49 +0000
@@ -556,6 +556,13 @@
556 name="+listing-simple"556 name="+listing-simple"
557 permission="zope.Public"557 permission="zope.Public"
558 template="../templates/pillar-listing-simple.pt"/>558 template="../templates/pillar-listing-simple.pt"/>
559 <browser:page
560 name="+get-involved"
561 for="lp.registry.interfaces.pillar.IPillar"
562 class="lp.registry.browser.pillar.PillarView"
563 facet="overview"
564 permission="zope.Public"
565 template="../templates/pillar-involvement-portlet.pt"/>
559 <facet566 <facet
560 facet="overview">567 facet="overview">
561 <browser:url568 <browser:url
562569
=== added file 'lib/lp/registry/browser/pillar.py'
--- lib/lp/registry/browser/pillar.py 1970-01-01 00:00:00 +0000
+++ lib/lp/registry/browser/pillar.py 2009-08-06 18:17:49 +0000
@@ -0,0 +1,26 @@
1# Copyright 2009 Canonical Ltd. This software is licensed under the
2# GNU Affero General Public License version 3 (see the file LICENSE).
3
4"""Common views for objects that implement `IPillar`."""
5
6__metaclass__ = type
7
8__all__ = [
9 'PillarView',
10 ]
11
12
13from canonical.launchpad.webapp.publisher import LaunchpadView
14
15
16class PillarView(LaunchpadView):
17 """A view for any `IPillar`."""
18
19 @property
20 def has_involvement(self):
21 """This `IPillar` uses Launchpad."""
22 pillar = self.context
23 return (
24 pillar.official_codehosting or pillar.official_malone
25 or pillar.official_answers or pillar.official_blueprints
26 or pillar.official_rosetta)
027
=== added file 'lib/lp/registry/browser/tests/pillar-views.txt'
--- lib/lp/registry/browser/tests/pillar-views.txt 1970-01-01 00:00:00 +0000
+++ lib/lp/registry/browser/tests/pillar-views.txt 2009-08-06 18:17:49 +0000
@@ -0,0 +1,45 @@
1Pillar views
2============
3
4Pillar views are used to display IPillar objects link distributions and
5products in a consistent fashion.
6
7The +get-involved presentation creates a portlet of links to encourage
8project involvement. Only links to official applications are rendered.
9
10
11 >>> distribution = factory.makeDistribution(name='umbra')
12 >>> login_person(distribution.owner)
13 >>> view = create_view(
14 ... distribution, '+get-involved', principal=distribution.owner)
15
16The has_involvement property is used to determine if the portlet should
17be rendered. The newly created pillar does not use any launchpad applications.
18
19 >>> view.has_involvement
20 False
21
22 >>> print view.render()
23 <BLANKLINE>
24
25Pillars that do use launchpad applications have an involvement menu.
26
27 >>> distribution.official_answers = True
28 >>> distribution.official_malone = True
29 >>> view = create_view(
30 ... distribution, '+get-involved', principal=distribution.owner)
31 >>> view.has_involvement
32 True
33
34 >>> print view.render()
35 <div id="involvement" class="portlet involvement">
36 <h2>Get Involved</h2>
37 <ul>
38 <li>
39 <a class="bugs" href="...">Report a Bug</a>
40 </li>
41 <li>
42 <a class="question" href="...">Ask a question</a>
43 </li>
44 </ul>
45 </div>
046
=== added file 'lib/lp/registry/templates/pillar-involvement-portlet.pt'
--- lib/lp/registry/templates/pillar-involvement-portlet.pt 1970-01-01 00:00:00 +0000
+++ lib/lp/registry/templates/pillar-involvement-portlet.pt 2009-08-06 18:17:49 +0000
@@ -0,0 +1,30 @@
1<div
2 xmlns:tal="http://xml.zope.org/namespaces/tal"
3 xmlns:i18n="http://xml.zope.org/namespaces/i18n"
4 id="involvement" class="portlet involvement"
5 tal:condition="view/has_involvement">
6 <h2>Get Involved</h2>
7
8 <ul>
9 <li tal:condition="context/official_malone">
10 <a class="bugs"
11 tal:attributes="href context/menu:bugs/filebug/url">Report a Bug</a>
12 </li>
13 <li tal:condition="context/official_answers">
14 <a class="question"
15 tal:attributes="href context/menu:answers/new/url">Ask a question</a>
16 </li>
17 <li tal:condition="context/official_rosetta">
18 <a class="translate"
19 tal:attributes="href context/menu:translations/overview/url">Help translate</a>
20 </li>
21 <li tal:condition="context/official_codehosting">
22 <a class="code"
23 tal:attributes="href context/menu:branches/branch_add/url">Submit code</a>
24 </li>
25 <li tal:condition="context/official_blueprints">
26 <a class="blueprint"
27 tal:attributes="href context/menu:specications/new/url">Register a Blueprint</a>
28 </li>
29 </ul>
30</div>
031