Merge lp:~wgrant/launchpad/header-4.0 into lp:launchpad

Proposed by William Grant
Status: Work in progress
Proposed branch: lp:~wgrant/launchpad/header-4.0
Merge into: lp:launchpad
Diff against target: 228 lines (+100/-8) (has conflicts)
7 files modified
lib/canonical/launchpad/icing/css/layout.css (+2/-1)
lib/lp/app/browser/launchpad.py (+77/-1)
lib/lp/app/browser/tests/watermark.txt (+12/-4)
lib/lp/app/templates/base-layout.pt (+1/-1)
lib/lp/registry/browser/personproduct.py (+1/-1)
lib/lp/registry/interfaces/distributionsourcepackage.py (+5/-0)
lib/lp/services/webapp/interfaces.py (+2/-0)
Text conflict in lib/lp/app/browser/launchpad.py
Text conflict in lib/lp/registry/interfaces/distributionsourcepackage.py
To merge this branch: bzr merge lp:~wgrant/launchpad/header-4.0
Reviewer Review Type Date Requested Status
Launchpad code reviewers Pending
Review via email: mp+306684@code.launchpad.net
To post a comment you must log in.

Unmerged revisions

17259. By William Grant

Merge devel.

17258. By William Grant

Merge devel.

17257. By William Grant

Fix Hierarchy property duplication. Breadcrumbs and titles now.

17256. By William Grant

Merge series-breadcrumbs-later. Breadcrumbs are totally broken.

17255. By William Grant

Merge WatermarkTalesAdapter into Hierarchy. The title is now generated from breadcrumbs.

17254. By William Grant

Fix "Recipes" breadcrumb by skipping IHeadingBreadcrumbs rather than IHeadingContexts.

17253. By William Grant

Merge series-breadcrumbs-later, resolving conflicts.

17252. By William Grant

TEMP

17251. By William Grant

Construct both elements in watermark:heading.

17250. By William Grant

Use breadcrumb text rather than object title in the watermark. DistributionSourcePackages need not duplicate the distribution.

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1=== modified file 'lib/canonical/launchpad/icing/css/layout.css'
2--- lib/canonical/launchpad/icing/css/layout.css 2014-11-27 06:34:33 +0000
3+++ lib/canonical/launchpad/icing/css/layout.css 2016-09-24 06:25:43 +0000
4@@ -104,6 +104,7 @@
5 .watermark-apps-portlet ul.facetmenu {
6 margin-top: 12px;
7 margin-left: -0.5em;
8+ border-bottom: 1px solid #747474;
9 white-space: nowrap;
10 }
11 .watermark-apps-portlet ul.facetmenu li {
12@@ -112,7 +113,7 @@
13 }
14 .watermark-apps-portlet ul.facetmenu li a,
15 .watermark-apps-portlet ul.facetmenu li span {
16- padding: 0.3em 0.5em;
17+ padding: 0.2em 0.5em;
18 margin-right: 0.4em;
19 }
20 .watermark-apps-portlet ul.facetmenu li a:link,
21
22=== modified file 'lib/lp/app/browser/launchpad.py'
23--- lib/lp/app/browser/launchpad.py 2016-06-22 21:04:30 +0000
24+++ lib/lp/app/browser/launchpad.py 2016-09-24 06:25:43 +0000
25@@ -394,6 +394,24 @@
26 return crumbs
27
28 @property
29+ def items_for_body(self):
30+ """Return breadcrumbs to display in the page body.
31+
32+ While all breadcrumbs should be included in the document title,
33+ the first few are represented specially in the body's header
34+ (aka. watermark), so we don't want to duplicate them.
35+ """
36+ crumbs = []
37+ print "items=%r" % self.items
38+ for crumb in self.items:
39+ if IHeadingBreadcrumb.providedBy(crumb):
40+ crumbs = []
41+ continue
42+ crumbs.append(crumb)
43+ print "crumbs=%r" % crumbs
44+ return crumbs
45+
46+ @property
47 def display_breadcrumbs(self):
48 """Return whether the breadcrumbs should be displayed."""
49 # If there is only one breadcrumb then it does not make sense
50@@ -402,7 +420,65 @@
51 # to display breadcrumbs either.
52 has_major_heading = IMajorHeadingView.providedBy(
53 self._naked_context_view)
54- return len(self.items_for_body) > 1 and not has_major_heading
55+<<<<<<< TREE
56+ return len(self.items_for_body) > 1 and not has_major_heading
57+=======
58+ return len(self.items_for_body) > 1 and not has_major_heading
59+
60+ @property
61+ def heading_breadcrumbs(self):
62+ crumbs = [
63+ crumb for crumb in self.items
64+ if IHeadingBreadcrumb.providedBy(crumb)]
65+ assert len(crumbs) <= 2
66+ return crumbs
67+
68+ def heading(self):
69+ """Return the heading text for the page.
70+
71+ If the view provides `IEditableContextTitle` then the top heading is
72+ rendered from the view's `title_edit_widget` and is generally
73+ editable.
74+
75+ Otherwise, if the context provides `IHeadingContext` then we return an
76+ H1, else an H2.
77+ """
78+ # Check the view; is the title editable?
79+ if IEditableContextTitle.providedBy(self.context):
80+ return self.context.title_edit_widget()
81+ # The title is static, but only the context's index view gets an H1.
82+ heading = 'h1' if IMajorHeadingView.providedBy(self.context) else 'h2'
83+ # If there is actually no root context, then it's a top-level
84+ # context-less page so Launchpad.net is shown as the branding.
85+ crumbs = self.heading_breadcrumbs
86+ if len(crumbs) >= 1:
87+ title = crumbs[0].detail
88+ else:
89+ title = 'Launchpad.net'
90+ # For non-editable titles, generate the static heading.
91+ markup = structured(
92+ "<%(heading)s>%(title)s</%(heading)s>",
93+ heading=heading, title=title).escapedtext
94+ if len(crumbs) >= 2:
95+ markup += structured(
96+ '\n<%(heading)s class="secondary">%(title)s</%(heading)s>',
97+ heading=heading, title=crumbs[1].detail).escapedtext
98+ return markup
99+
100+ def logo(self):
101+ """Return the logo image for the top header breadcrumb's context."""
102+ logo_context = (
103+ self.heading_breadcrumbs[0].context if self.heading_breadcrumbs
104+ else None)
105+ adapter = queryAdapter(logo_context, IPathAdapter, 'image')
106+ if logo_context != self.context.context and logo_context is not None:
107+ return structured(
108+ '<a href="%s">%s</a>',
109+ canonical_url(logo_context, rootsite='mainsite'),
110+ structured(adapter.logo())).escapedtext
111+ else:
112+ return adapter.logo()
113+>>>>>>> MERGE-SOURCE
114
115 @property
116 def heading_breadcrumbs(self):
117
118=== modified file 'lib/lp/app/browser/tales.py'
119=== modified file 'lib/lp/app/browser/tests/watermark.txt'
120--- lib/lp/app/browser/tests/watermark.txt 2015-07-08 16:05:11 +0000
121+++ lib/lp/app/browser/tests/watermark.txt 2016-09-24 06:25:43 +0000
122@@ -4,14 +4,14 @@
123
124 The watermark is the image and heading used on all the main Launchpad
125 pages. The image and heading are determined by Hierarchy from the
126-IRootContext for the context object.
127+IHeadingBreadcrumbs in the context object's breadcrumbs.
128
129
130 Watermark headings
131 ==================
132
133 Hierarchy.heading() is used when you want a heading for the nearest
134-object that implements IRootContext.
135+object that implements IHeadingBreadcrumb.
136
137 >>> from lp.app.browser.launchpad import Hierarchy
138 >>> from lp.services.webapp.servers import LaunchpadTestRequest
139@@ -26,7 +26,7 @@
140 ... req.traversed_objects.append(view)
141 ... return Hierarchy(view, req)
142
143-Products directly implement IRootContext.
144+Products directly implement IHeadingContext.
145
146 >>> widget = factory.makeProduct(displayname='Widget')
147 >>> print get_hierarchy(widget).heading()
148@@ -38,7 +38,7 @@
149 >>> print get_hierarchy(dev_focus).heading()
150 <h...><a...>Widget</a></h...>
151
152-ProjectGroups also directly implement IRootContext ...
153+ProjectGroups also directly implement IHeadingContext ...
154
155 >>> kde = factory.makeProject(displayname='KDE')
156 >>> print get_hierarchy(kde).heading()
157@@ -50,6 +50,14 @@
158 >>> print get_hierarchy(mint).heading()
159 <h...><a...>Mint Linux</a></h...>
160
161+... and distribution source packacges ...
162+
163+ >>> dpkg = factory.makeDistributionSourcePackage(
164+ ... distribution=mint, sourcepackagename=u"dpkg")
165+ >>> print test_tales('view/watermark:heading', view=view(dpkg))
166+ <h...>Mint Linux</h...>
167+ <h...>“dpkg” package</h...>
168+
169 ... and people ...
170
171 >>> eric = factory.makePerson(displayname="Eric the Viking")
172
173=== modified file 'lib/lp/app/templates/base-layout.pt'
174--- lib/lp/app/templates/base-layout.pt 2016-09-14 11:13:06 +0000
175+++ lib/lp/app/templates/base-layout.pt 2016-09-24 06:25:43 +0000
176@@ -110,7 +110,7 @@
177 >Page Label
178 </h1>
179 <tal:breadcrumbs replace="structure view/@@+hierarchy">
180- ProjectName > Branches > Merge Proposals > fix-for-navigation
181+ Merge Proposals > fix-for-navigation
182 </tal:breadcrumbs>
183 <div id="registration" class="registering"
184 tal:condition="not: view/macro:is-page-contentless">
185
186=== modified file 'lib/lp/registry/browser/personproduct.py'
187--- lib/lp/registry/browser/personproduct.py 2015-07-08 16:05:11 +0000
188+++ lib/lp/registry/browser/personproduct.py 2016-09-24 06:25:43 +0000
189@@ -50,7 +50,7 @@
190
191 @property
192 def text(self):
193- return self.context.product.displayname
194+ return self.context.product.title
195
196 @property
197 def url(self):
198
199=== modified file 'lib/lp/registry/interfaces/distributionsourcepackage.py'
200--- lib/lp/registry/interfaces/distributionsourcepackage.py 2015-10-12 16:16:28 +0000
201+++ lib/lp/registry/interfaces/distributionsourcepackage.py 2016-09-24 06:25:43 +0000
202@@ -40,8 +40,13 @@
203 from lp.soyuz.enums import ArchivePurpose
204
205
206+<<<<<<< TREE
207 class IDistributionSourcePackage(IHeadingContext, IBugTarget, IHasBranches,
208 IHasMergeProposals, IHasOfficialBugTags,
209+=======
210+class IDistributionSourcePackage(IBugTarget, IHasBranches,
211+ IHasMergeProposals, IHasOfficialBugTags,
212+>>>>>>> MERGE-SOURCE
213 IStructuralSubscriptionTarget,
214 IQuestionTarget, IHasDrivers,
215 IHasGitRepositories):
216
217=== modified file 'lib/lp/services/webapp/interfaces.py'
218--- lib/lp/services/webapp/interfaces.py 2016-09-14 11:12:13 +0000
219+++ lib/lp/services/webapp/interfaces.py 2016-09-24 06:25:43 +0000
220@@ -236,6 +236,8 @@
221 class IBreadcrumb(Interface):
222 """A breadcrumb link."""
223
224+ context = Attribute("Object that this breadcrumb represents.")
225+
226 url = Attribute('Absolute url of this breadcrumb.')
227
228 text = Attribute('Text of this breadcrumb.')