=== modified file 'lib/canonical/launchpad/pagetitles.py' --- lib/canonical/launchpad/pagetitles.py 2009-09-22 00:49:37 +0000 +++ lib/canonical/launchpad/pagetitles.py 2009-09-22 15:03:45 +0000 @@ -402,13 +402,6 @@ hasannouncements_index = ContextDisplayName('%s news and announcements') -def hasspecifications_specs(context, view): - """Return the secifications title for the context.""" - if IPerson.providedBy(context): - return "Blueprints involving %s" % context.title - else: - return "Blueprints for %s" % context.title - hassprints_sprints = ContextTitle("Events related to %s") # launchpad_debug doesn't need a title. === modified file 'lib/lp/blueprints/browser/specificationgoal.py' --- lib/lp/blueprints/browser/specificationgoal.py 2009-09-18 19:47:24 +0000 +++ lib/lp/blueprints/browser/specificationgoal.py 2009-09-22 14:54:36 +0000 @@ -30,6 +30,7 @@ """ label = "Set feature goals" + page_title = "Feature goals" @cachedproperty def spec_filter(self): === modified file 'lib/lp/blueprints/browser/specificationtarget.py' --- lib/lp/blueprints/browser/specificationtarget.py 2009-09-22 09:23:42 +0000 +++ lib/lp/blueprints/browser/specificationtarget.py 2009-09-22 14:54:36 +0000 @@ -6,6 +6,7 @@ __metaclass__ = type __all__ = [ + 'HasSpecificationsMenuMixin', 'HasSpecificationsView', 'RegisterABlueprintButtonView', 'SpecificationAssignmentsView', @@ -30,7 +31,7 @@ from canonical.config import config from canonical.launchpad import _ -from canonical.launchpad.webapp import LaunchpadView +from canonical.launchpad.webapp import LaunchpadView, Link from canonical.launchpad.webapp.batching import BatchNavigator from canonical.launchpad.webapp.breadcrumb import Breadcrumb from canonical.launchpad.helpers import shortlist @@ -39,6 +40,48 @@ from canonical.lazr.utils import smartquote +class HasSpecificationsMenuMixin(object): + + def listall(self): + """Return a link to show all blueprints.""" + text = 'List all blueprints' + return Link('+specs?show=all', text, icon='blueprint') + + def listaccepted(self): + """Return a link to show the approved goals.""" + text = 'List approved blueprints' + return Link('+specs?acceptance=accepted', text, icon='blueprint') + + def listproposed(self): + """Return a link to show the proposed goals.""" + text = 'List proposed blueprints' + return Link('+specs?acceptance=proposed', text, icon='blueprint') + + def listdeclined(self): + """Return a link to show the declined goals.""" + text = 'List declined blueprints' + return Link('+specs?acceptance=declined', text, icon='blueprint') + + def doc(self): + text = 'List documentation' + return Link('+documentation', text, icon='info') + + def setgoals(self): + """Return a link to set the series goals.""" + text = 'Set series goals' + return Link('+setgoals', text, icon='edit') + + def assignments(self): + """Return a link to show the people assigned to the blueprint.""" + text = 'Assignments' + return Link('+assignments', text, icon='person') + + def new(self): + """Return a link to register a blueprint.""" + text = 'Register a blueprint' + return Link('+addspec', text, icon='add') + + class HasSpecificationsView(LaunchpadView): """Base class for several context-specific views that involve lists of specifications. @@ -78,7 +121,6 @@ # replacing the conditional execution with polymorphism. # See https://bugs.launchpad.net/blueprint/+bug/173972. def initialize(self): - mapping = {'name': self.context.displayname} if IPerson.providedBy(self.context): self.is_person = True elif (IDistribution.providedBy(self.context) or @@ -105,11 +147,6 @@ else: raise AssertionError, 'Unknown blueprint listing site' - if self.is_person: - self.title = _('Specifications involving $name', mapping=mapping) - else: - self.title = _('Specifications for $name', mapping=mapping) - if IHasDrivers.providedBy(self.context): self.has_drivers = True @@ -117,6 +154,14 @@ self.specs, self.request, size=config.launchpad.default_batch_size) + @property + def label(self): + mapping = {'name': self.context.displayname} + if self.is_person: + return _('Blueprints involving $name', mapping=mapping) + else: + return _('Blueprints for $name', mapping=mapping) + def mdzCsv(self): """Quick hack for mdz, to get csv dump of specs.""" import csv @@ -326,6 +371,7 @@ class SpecificationDocumentationView(HasSpecificationsView): """View for blueprints +documentation page.""" + page_title = "Documentation" @property def label(self): @@ -355,17 +401,7 @@ """ % canonical_url(target, rootsite='blueprints') -class HasSpecificationsOnBlueprintsVHostBreadcrumb(Breadcrumb): - rootsite = 'blueprints' - - @property - def text(self): - return 'Blueprints for %s' % self.context.title - - -class PersonOnBlueprintsVHostBreadcrumb(Breadcrumb): - rootsite = 'blueprints' - - @property - def text(self): - return 'Blueprints involving %s' % self.context.displayname +class BlueprintsVHostBreadcrumb(Breadcrumb): + rootsite = 'blueprints' + text = 'Blueprints' + === modified file 'lib/lp/blueprints/browser/sprint.py' --- lib/lp/blueprints/browser/sprint.py 2009-09-21 12:39:15 +0000 +++ lib/lp/blueprints/browser/sprint.py 2009-09-22 14:54:36 +0000 @@ -46,7 +46,7 @@ from lp.app.interfaces.headings import IMajorHeadingView from lp.blueprints.browser.specificationtarget import ( - HasSpecificationsView) + HasSpecificationsMenuMixin, HasSpecificationsView) from lp.blueprints.interfaces.specification import ( SpecificationDefinitionStatus, SpecificationFilter, SpecificationPriority, SpecificationSort) @@ -110,32 +110,16 @@ return Link('+branding', text, summary, icon='edit') -class SprintSpecificationsMenu(ApplicationMenu): - +class SprintSpecificationsMenu(NavigationMenu, + HasSpecificationsMenuMixin): usedfor = ISprint facet = 'specifications' - links = ['assignments', 'declined', 'settopics', 'addspec'] - - def assignments(self): - text = 'Assignments' - summary = 'View the specification assignments' - return Link('+assignments', text, summary, icon='info') - - def declined(self): - text = 'List declined blueprints' - summary = 'Show topics that were not accepted for discussion' - return Link('+specs?acceptance=declined', text, summary, icon='info') + links = ['assignments', 'listdeclined', 'settopics', 'new'] @enabled_with_permission('launchpad.Driver') def settopics(self): text = 'Set agenda' - summary = 'Approve or defer topics for discussion' - return Link('+settopics', text, summary, icon='edit') - - def addspec(self): - text = 'Register a blueprint' - summary = 'Register a new blueprint for this meeting' - return Link('+addspec', text, summary, icon='info') + return Link('+settopics', text, icon='edit') class SprintSetNavigation(GetitemNavigation): === modified file 'lib/lp/blueprints/browser/tests/test_breadcrumbs.py' --- lib/lp/blueprints/browser/tests/test_breadcrumbs.py 2009-09-16 03:37:47 +0000 +++ lib/lp/blueprints/browser/tests/test_breadcrumbs.py 2009-09-22 14:54:36 +0000 @@ -29,16 +29,14 @@ self.product_specs_url, [self.root, self.product]) last_crumb = crumbs[-1] self.assertEquals(last_crumb.url, self.product_specs_url) - self.assertEquals( - last_crumb.text, 'Blueprints for %s' % self.product.title) + self.assertEquals(last_crumb.text, 'Blueprints') def test_person(self): crumbs = self._getBreadcrumbs( self.person_specs_url, [self.root, self.person]) last_crumb = crumbs[-1] self.assertEquals(last_crumb.url, self.person_specs_url) - self.assertEquals(last_crumb.text, - 'Blueprints involving %s' % self.person.displayname) + self.assertEquals(last_crumb.text, 'Blueprints') class TestSpecificationBreadcrumb(BaseBreadcrumbTestCase): === modified file 'lib/lp/blueprints/configure.zcml' --- lib/lp/blueprints/configure.zcml 2009-09-16 03:37:47 +0000 +++ lib/lp/blueprints/configure.zcml 2009-09-22 14:57:34 +0000 @@ -236,12 +236,12 @@ name="blueprints" provides="canonical.launchpad.webapp.interfaces.IBreadcrumb" for="lp.blueprints.interfaces.specificationtarget.IHasSpecifications" - factory="lp.blueprints.browser.specificationtarget.HasSpecificationsOnBlueprintsVHostBreadcrumb" + factory="lp.blueprints.browser.specificationtarget.BlueprintsVHostBreadcrumb" permission="zope.Public"/> === modified file 'lib/lp/blueprints/stories/blueprints/01-creation.txt' --- lib/lp/blueprints/stories/blueprints/01-creation.txt 2009-09-19 01:54:04 +0000 +++ lib/lp/blueprints/stories/blueprints/01-creation.txt 2009-09-22 14:54:36 +0000 @@ -64,7 +64,7 @@ ... user_browser.contents, 'menu-link-new'): ... print tag Register a blueprint + class="menu-link-new...>Register a blueprint === From a distribution series === @@ -85,7 +85,7 @@ ... user_browser.contents, 'menu-link-new'): ... print tag Register a blueprint + class="menu-link-new...>Register a blueprint === From a product === @@ -106,7 +106,7 @@ ... user_browser.contents, 'menu-link-new'): ... print tag Register a blueprint + class="menu-link-new...>Register a blueprint For products without any blueprints, users can follow the special "register it here as a blueprint" link: @@ -137,7 +137,7 @@ ... user_browser.contents, 'menu-link-new'): ... print tag Register a blueprint + class="menu-link-new...>Register a blueprint === From a project === @@ -158,7 +158,7 @@ ... user_browser.contents, 'menu-link-new'): ... print tag Register a blueprint + class="menu-link-new...>Register a blueprint === From a sprint === @@ -176,10 +176,10 @@ Users can also follow the textual "Register a blueprint" link: >>> for tag in find_tags_by_class( - ... user_browser.contents, 'menu-link-addspec'): + ... user_browser.contents, 'menu-link-new'): ... print tag Register a blueprint + class="menu-link-new...>Register a blueprint == Registering a blueprint == === modified file 'lib/lp/blueprints/stories/blueprints/07-milestones.txt' --- lib/lp/blueprints/stories/blueprints/07-milestones.txt 2009-09-21 19:15:03 +0000 +++ lib/lp/blueprints/stories/blueprints/07-milestones.txt 2009-09-22 14:54:36 +0000 @@ -17,7 +17,7 @@ >>> admin_browser.getLink('Target milestone').click() >>> print admin_browser.title Target to a milestone : Support Objects : - Blueprints for Mozilla Firefox : Mozilla Firefox + Blueprints : Mozilla Firefox >>> back_link = admin_browser.getLink('Support Objects') >>> back_link.url 'http://blueprints.launchpad.dev/firefox/+spec/canvas' === modified file 'lib/lp/blueprints/stories/blueprints/xx-overview.txt' --- lib/lp/blueprints/stories/blueprints/xx-overview.txt 2009-09-21 19:15:03 +0000 +++ lib/lp/blueprints/stories/blueprints/xx-overview.txt 2009-09-22 14:54:36 +0000 @@ -44,6 +44,7 @@ >>> main = find_main_content(user_browser.contents) >>> print extract_text(main).encode('ascii', 'backslashreplace') Blueprints for 1.0 + ... Launchpad lets projects track the features they intend to implement... Let's target an existing Mozilla Firefox blueprint to the 1.0 series: @@ -144,6 +145,7 @@ >>> main = find_main_content(user_browser.contents) >>> print extract_text(main).encode('ascii', 'backslashreplace') Blueprints for Grumpy + ... Launchpad lets projects track the features they intend to implement... Let's target an existing Ubuntu blueprint to the Grumpy series: === modified file 'lib/lp/blueprints/stories/blueprints/xx-personviews.txt' --- lib/lp/blueprints/stories/blueprints/xx-personviews.txt 2009-09-18 12:47:26 +0000 +++ lib/lp/blueprints/stories/blueprints/xx-personviews.txt 2009-09-22 14:54:36 +0000 @@ -8,8 +8,8 @@ involving that person. >>> browser.open('http://blueprints.launchpad.dev/~name16') - >>> browser.title - 'Blueprints involving Foo Bar' + >>> print browser.title + Blueprints : Foo Bar >>> soup = find_main_content(browser.contents) >>> soup('h1') [

Blueprints involving Foo Bar

] @@ -73,9 +73,10 @@ are part of the workload for the team. It then shows the workloads for each member of the team, using batching. + >>> from canonical.launchpad.helpers import backslashreplace >>> browser.open('http://blueprints.launchpad.dev/~admins') - >>> browser.title - 'Blueprints involving Launchpad Administrators' + >>> print backslashreplace(browser.title) + Blueprints : \u201cLaunchpad Administrators\u201d team >>> browser.getLink('Workload').click() >>> browser.url '.../~admins/+specworkload' === modified file 'lib/lp/blueprints/stories/sprints/sprint-settopics.txt' --- lib/lp/blueprints/stories/sprints/sprint-settopics.txt 2009-09-21 12:43:33 +0000 +++ lib/lp/blueprints/stories/sprints/sprint-settopics.txt 2009-09-22 14:54:36 +0000 @@ -70,7 +70,7 @@ >>> print cprov_browser.title Review discussion topics for “Ubuntu DevSummit Guacamole” sprint : - Blueprints for Ubuntu DevSummit Guacamole : + Blueprints : Ubuntu DevSummit Guacamole : Meetings === modified file 'lib/lp/blueprints/templates/hasspecifications-specs.pt' --- lib/lp/blueprints/templates/hasspecifications-specs.pt 2009-07-17 17:59:07 +0000 +++ lib/lp/blueprints/templates/hasspecifications-specs.pt 2009-09-22 14:54:36 +0000 @@ -3,18 +3,16 @@ xmlns:tal="http://xml.zope.org/namespaces/tal" xmlns:metal="http://xml.zope.org/namespaces/metal" xmlns:i18n="http://xml.zope.org/namespaces/i18n" - xml:lang="en" - lang="en" - dir="ltr" - metal:use-macro="context/@@main_template/master" + metal:use-macro="view/macro:page/main_side" i18n:domain="launchpad" > - -
- + + +
+
Blueprints involving -

Blueprints for

-
=== modified file 'lib/lp/blueprints/templates/specificationtarget-assignments.pt' --- lib/lp/blueprints/templates/specificationtarget-assignments.pt 2009-09-22 00:13:14 +0000 +++ lib/lp/blueprints/templates/specificationtarget-assignments.pt 2009-09-22 14:54:36 +0000 @@ -3,12 +3,17 @@ xmlns:tal="http://xml.zope.org/namespaces/tal" xmlns:metal="http://xml.zope.org/namespaces/metal" xmlns:i18n="http://xml.zope.org/namespaces/i18n" - metal:use-macro="view/macro:page/main_only" + metal:use-macro="view/macro:page/main_side" i18n:domain="launchpad" > + + +
+ +

@@ -88,8 +93,6 @@

-
-
=== modified file 'lib/lp/registry/browser/distribution.py' --- lib/lp/registry/browser/distribution.py 2009-09-16 00:40:53 +0000 +++ lib/lp/registry/browser/distribution.py 2009-09-22 14:54:36 +0000 @@ -47,6 +47,8 @@ from zope.security.interfaces import Unauthorized from canonical.cachedproperty import cachedproperty +from lp.blueprints.browser.specificationtarget import ( + HasSpecificationsMenuMixin) from lp.registry.browser.announcement import HasAnnouncementsView from lp.registry.browser.menu import ( IRegistryCollectionNavigationMenu, RegistryCollectionActionMenuBase) @@ -454,31 +456,12 @@ return Link('+subscribe', text, icon='edit') -class DistributionSpecificationsMenu(ApplicationMenu): - +class DistributionSpecificationsMenu(NavigationMenu, + HasSpecificationsMenuMixin): usedfor = IDistribution facet = 'specifications' links = ['listall', 'doc', 'assignments', 'new'] - def listall(self): - text = 'List all blueprints' - return Link('+specs?show=all', text, icon='info') - - def assignments(self): - text = 'Assignments' - return Link('+assignments', text, icon='info') - - def doc(self): - text = 'Documentation' - summary = 'List all complete informational specifications' - return Link('+documentation', text, summary, - icon='info') - - def new(self): - text = 'Register a blueprint' - summary = 'Register a new blueprint for %s' % self.context.title - return Link('+addspec', text, summary, icon='add') - class DistributionPackageSearchView(PackageSearchViewBase): """Customised PackageSearchView for Distribution""" === modified file 'lib/lp/registry/browser/distroseries.py' --- lib/lp/registry/browser/distroseries.py 2009-09-15 01:17:46 +0000 +++ lib/lp/registry/browser/distroseries.py 2009-09-22 14:54:36 +0000 @@ -28,6 +28,8 @@ from canonical.database.constants import UTC_NOW from canonical.launchpad import _ from canonical.launchpad import helpers +from lp.blueprints.browser.specificationtarget import ( + HasSpecificationsMenuMixin) from lp.bugs.browser.bugtask import BugTargetTraversalMixin from lp.soyuz.browser.build import BuildRecordsView from canonical.launchpad.browser.packagesearch import PackageSearchViewBase @@ -49,7 +51,7 @@ from canonical.launchpad.webapp.launchpadform import ( LaunchpadEditFormView, LaunchpadFormView) from canonical.launchpad.webapp.menu import ( - ApplicationMenu, Link, enabled_with_permission) + ApplicationMenu, Link, NavigationMenu, enabled_with_permission) from canonical.launchpad.webapp.publisher import ( canonical_url, stepthrough, stepto) from canonical.widgets.itemswidgets import LaunchpadDropdownWidget @@ -225,43 +227,12 @@ return Link('+subscribe', 'Subscribe to bug mail') -class DistroSeriesSpecificationsMenu(ApplicationMenu): +class DistroSeriesSpecificationsMenu(NavigationMenu, + HasSpecificationsMenuMixin): usedfor = IDistroSeries facet = 'specifications' - links = ['listall', 'table', 'setgoals', 'listdeclined', 'new'] - - def listall(self): - text = 'List all blueprints' - return Link('+specs?show=all', text, icon='info') - - def listapproved(self): - text = 'List approved blueprints' - return Link('+specs?acceptance=accepted', text, icon='info') - - def listproposed(self): - text = 'List proposed blueprints' - return Link('+specs?acceptance=proposed', text, icon='info') - - def listdeclined(self): - text = 'List declined blueprints' - summary = 'Show the goals which have been declined' - return Link('+specs?acceptance=declined', text, icon='info') - - def setgoals(self): - text = 'Set series goals' - summary = 'Approve or decline feature goals that have been proposed' - return Link('+setgoals', text, icon='info') - - def table(self): - text = 'Assignments' - summary = 'Show the assignee, drafter and approver of these specs' - return Link('+assignments', text, icon='info') - - def new(self): - text = 'Register a blueprint' - summary = 'Register a new blueprint for %s' % self.context.title - return Link('+addspec', text, summary, icon='add') + links = ['listall', 'listdeclined', 'assignments', 'setgoals', 'new'] class DistroSeriesPackageSearchView(PackageSearchViewBase): === modified file 'lib/lp/registry/browser/person.py' --- lib/lp/registry/browser/person.py 2009-09-20 07:13:52 +0000 +++ lib/lp/registry/browser/person.py 2009-09-22 15:00:08 +0000 @@ -775,7 +775,7 @@ return Link('+commentedbugs', text, summary=summary) -class PersonSpecsMenu(ApplicationMenu): +class PersonSpecsMenu(NavigationMenu): usedfor = IPerson facet = 'specifications' @@ -786,28 +786,28 @@ def registrant(self): text = 'Registrant' summary = 'List specs registered by %s' % self.context.displayname - return Link('+specs?role=registrant', text, summary, icon='spec') + return Link('+specs?role=registrant', text, summary, icon='blueprint') def approver(self): text = 'Approver' summary = 'List specs with %s is supposed to approve' % ( self.context.displayname) - return Link('+specs?role=approver', text, summary, icon='spec') + return Link('+specs?role=approver', text, summary, icon='blueprint') def assignee(self): text = 'Assignee' summary = 'List specs for which %s is the assignee' % ( self.context.displayname) - return Link('+specs?role=assignee', text, summary, icon='spec') + return Link('+specs?role=assignee', text, summary, icon='blueprint') def drafter(self): text = 'Drafter' summary = 'List specs drafted by %s' % self.context.displayname - return Link('+specs?role=drafter', text, summary, icon='spec') + return Link('+specs?role=drafter', text, summary, icon='blueprint') def subscriber(self): text = 'Subscriber' - return Link('+specs?role=subscriber', text, icon='spec') + return Link('+specs?role=subscriber', text, icon='blueprint') def feedback(self): text = 'Feedback requests' === modified file 'lib/lp/registry/browser/product.py' --- lib/lp/registry/browser/product.py 2009-09-18 01:34:06 +0000 +++ lib/lp/registry/browser/product.py 2009-09-22 14:54:37 +0000 @@ -58,6 +58,8 @@ from canonical.launchpad import _ from canonical.launchpad.fields import PillarAliases, PublicPersonChoice from lp.app.interfaces.headings import IEditableContextTitle +from lp.blueprints.browser.specificationtarget import ( + HasSpecificationsMenuMixin) from lp.bugs.interfaces.bugtask import RESOLVED_BUGTASK_STATUSES from lp.bugs.interfaces.bugwatch import IBugTracker from lp.services.worlddata.interfaces.country import ICountry @@ -475,32 +477,11 @@ return Link('+subscribe', text, icon='edit') -class ProductSpecificationsMenu(ApplicationMenu): - +class ProductSpecificationsMenu(NavigationMenu, + HasSpecificationsMenuMixin): usedfor = IProduct facet = 'specifications' - links = ['listall', 'doc', 'table', 'new'] - - def listall(self): - text = 'List all blueprints' - summary = 'Show all specifications for %s' % self.context.title - return Link('+specs?show=all', text, summary, icon='info') - - def doc(self): - text = 'List documentation' - summary = 'List all complete informational specifications' - return Link('+documentation', text, summary, - icon='info') - - def table(self): - text = 'Assignments' - summary = 'Show the full assignment of work, drafting and approving' - return Link('+assignments', text, summary, icon='info') - - def new(self): - text = 'Register a blueprint' - summary = 'Register a new blueprint for %s' % self.context.title - return Link('+addspec', text, summary, icon='add') + links = ['listall', 'doc', 'assignments', 'new'] def _sort_distros(a, b): === modified file 'lib/lp/registry/browser/productseries.py' --- lib/lp/registry/browser/productseries.py 2009-09-15 02:16:19 +0000 +++ lib/lp/registry/browser/productseries.py 2009-09-22 14:54:37 +0000 @@ -39,6 +39,8 @@ from canonical.cachedproperty import cachedproperty from canonical.launchpad import _ from lp.code.browser.branchref import BranchRef +from lp.blueprints.browser.specificationtarget import ( + HasSpecificationsMenuMixin) from lp.blueprints.interfaces.specification import ( ISpecificationSet, SpecificationImplementationStatus) from lp.bugs.interfaces.bugtask import BugTaskStatus @@ -247,7 +249,8 @@ return Link('+subscribe', 'Subscribe to bug mail') -class ProductSeriesSpecificationsMenu(ApplicationMenu): +class ProductSeriesSpecificationsMenu(NavigationMenu, + HasSpecificationsMenuMixin): """Specs menu for ProductSeries. This menu needs to keep track of whether we are showing all the @@ -258,46 +261,7 @@ usedfor = IProductSeries facet = 'specifications' - links = ['listall', 'table', 'setgoals', 'listdeclined', 'new'] - - def listall(self): - """Return a link to show all blueprints.""" - text = 'List all blueprints' - return Link('+specs?show=all', text, icon='info') - - def listaccepted(self): - """Return a link to show the approved goals.""" - text = 'List approved blueprints' - return Link('+specs?acceptance=accepted', text, icon='info') - - def listproposed(self): - """Return a link to show the proposed goals.""" - text = 'List proposed blueprints' - return Link('+specs?acceptance=proposed', text, icon='info') - - def listdeclined(self): - """Return a link to show the declined goals.""" - text = 'List declined blueprints' - summary = 'Show the goals which have been declined' - return Link('+specs?acceptance=declined', text, summary, icon='info') - - def setgoals(self): - """Return a link to set the series goals.""" - text = 'Set series goals' - summary = 'Approve or decline feature goals that have been proposed' - return Link('+setgoals', text, summary, icon='edit') - - def table(self): - """Return a link to show the people assigned to the blueprint.""" - text = 'Assignments' - summary = 'Show the assignee, drafter and approver of these specs' - return Link('+assignments', text, summary, icon='info') - - def new(self): - """Return a link to register a blueprint.""" - text = 'Register a blueprint' - summary = 'Register a new blueprint for %s' % self.context.title - return Link('+addspec', text, summary, icon='add') + links = ['listall', 'assignments', 'setgoals', 'listdeclined', 'new'] class ProductSeriesOverviewNavigationMenu(NavigationMenu): === modified file 'lib/lp/registry/browser/project.py' --- lib/lp/registry/browser/project.py 2009-09-15 20:41:36 +0000 +++ lib/lp/registry/browser/project.py 2009-09-22 14:54:37 +0000 @@ -44,6 +44,8 @@ from canonical.launchpad import _ from canonical.launchpad.webapp.interfaces import NotFoundError from canonical.launchpad.webapp.menu import NavigationMenu +from lp.blueprints.browser.specificationtarget import ( + HasSpecificationsMenuMixin) from lp.registry.interfaces.product import IProductSet from lp.registry.interfaces.project import ( IProject, IProjectSeries, IProjectSet) @@ -267,30 +269,12 @@ links = ('branding', 'reassign', 'driver', 'administer') -class ProjectSpecificationsMenu(ApplicationMenu): - +class ProjectSpecificationsMenu(NavigationMenu, + HasSpecificationsMenuMixin): usedfor = IProject facet = 'specifications' links = ['listall', 'doc', 'assignments', 'new'] - def listall(self): - text = 'List all blueprints' - return Link('+specs?show=all', text, icon='info') - - def doc(self): - text = 'List documentation' - summary = 'Show all completed informational specifications' - return Link('+documentation', text, summary, icon="info") - - def assignments(self): - text = 'Assignments' - return Link('+assignments', text, icon='info') - - def new(self): - text = 'Register a blueprint' - summary = 'Register a new blueprint for %s' % self.context.title - return Link('+addspec', text, summary, icon='add') - class ProjectAnswersMenu(QuestionCollectionAnswersMenu): """Menu for the answers facet of projects."""