src/doc: HierarchyList use new templates
[nit.git] / src / doc / html_templates / html_templates.nit
1 # This file is part of NIT ( http://www.nitlanguage.org ).
2 #
3 # Licensed under the Apache License, Version 2.0 (the "License");
4 # you may not use this file except in compliance with the License.
5 # You may obtain a copy of the License at
6 #
7 # http://www.apache.org/licenses/LICENSE-2.0
8 #
9 # Unless required by applicable law or agreed to in writing, software
10 # distributed under the License is distributed on an "AS IS" BASIS,
11 # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 # See the License for the specific language governing permissions and
13 # limitations under the License.
14
15 # Introduces templates that compose the documentation HTML rendering.
16 module html_templates
17
18 import html_model
19 import html::bootstrap
20 import doc_phases::doc_structure
21 import doc_phases::doc_hierarchies
22
23 # Renders the page as HTML.
24 redef class DocPage
25 super Template
26
27 # Page url.
28 var html_url: String is writable, noinit
29
30 # Directory where css, js and other assets can be found.
31 var shareurl: String is writable, noinit
32
33 # Attributes of the body tag element.
34 var body_attrs = new Array[TagAttribute]
35
36 # Top menu template if any.
37 var topmenu: DocTopMenu is writable, noinit
38
39 # Sidebar template if any.
40 var sidebar: nullable TplSidebar = null is writable
41
42 # Content of the page in form a TplSection.
43 # TODO remove when other templates are migrated.
44 var sections = new Array[TplSection]
45
46 # Footer content if any.
47 var footer: nullable Writable = null is writable
48
49 # JS scripts to append at the end of the body
50 var scripts = new Array[TplScript]
51
52 # Adds a section to this page.
53 # TODO remove when other templates are migrated.
54 fun add_section(section: TplSection) do
55 sections.add section
56 end
57
58 # Renders the html `<head>`.
59 private fun render_head do
60 var css = (self.shareurl / "css").html_escape
61 var vendors = (self.shareurl / "vendors").html_escape
62
63 addn "<!DOCTYPE html>"
64 addn "<head>"
65 addn " <meta charset='utf-8'/>"
66 addn " <!--link rel='stylesheet' href='{css}/Nitdoc.UI.css' type='text/css'/-->"
67 addn " <link rel='stylesheet' href='{vendors}/bootstrap/css/bootstrap.min.css'/>"
68 addn " <link rel='stylesheet' href='{css}/nitdoc.bootstrap.css'/>"
69 addn " <link rel='stylesheet' href='{css}/nitdoc.css'/>"
70 addn " <link rel='stylesheet' href='{css}/Nitdoc.QuickSearch.css'/>"
71 addn " <link rel='stylesheet' href='{css}/Nitdoc.ModalBox.css'/>"
72 addn " <link rel='stylesheet' href='{css}/Nitdoc.GitHub.css'/>"
73 addn " <title>{title.html_escape}</title>"
74 addn "</head>"
75 add "<body"
76 for attr in body_attrs do add attr
77 addn ">"
78 end
79
80 # Renders the sidebar template.
81 #
82 # Sidebar is automatically populated with a summary of all sections
83 # TODO remove summary generation when other templates are migrated.
84 private fun render_sidebar do
85 if sidebar == null then return
86 var summary = new TplSummary.with_order(0)
87 for section in sections do
88 section.render_summary summary
89 end
90 sidebar.boxes.add summary
91 add sidebar.as(not null)
92 end
93
94 # Renders the footer and content.
95 private fun render_content do
96 for section in sections do add section
97 if footer != null then
98 addn "<div class='well footer'>"
99 add footer.as(not null)
100 addn "</div>"
101 end
102 end
103
104 # Render JS scripts
105 private fun render_footer do
106 var vendors = (self.shareurl / "vendors").html_escape
107 var js = (self.shareurl / "js").html_escape
108
109 addn "<script src='{vendors}/jquery/jquery-1.11.1.min.js'></script>"
110 addn "<script src='{vendors}/jquery/jquery-ui-1.10.4.custom.min.js'></script>"
111 addn "<script src='{vendors}/bootstrap/js/bootstrap.min.js'></script>"
112 addn "<script data-main='{js}/nitdoc' src='{js}/lib/require.js'></script>"
113 for script in scripts do add script
114 addn """<script>
115 $(function () {
116 $("[data-toggle='tooltip']").tooltip();
117 $("[data-toggle='popover']").popover();
118 });
119 </script>"""
120 addn "</body>"
121 addn "</html>"
122 end
123
124 # Render the whole page
125 redef fun rendering do
126 render_head
127 addn "<div class='container-fluid'>"
128 addn " <div class='row'>"
129 add topmenu
130 addn " </div>"
131 addn " <div class='row' id='content'>"
132 if sidebar != null then
133 addn "<div class='col col-xs-3 col-lg-2'>"
134 render_sidebar
135 addn "</div>"
136 addn "<div class='col col-xs-9 col-lg-10' data-spy='scroll' data-target='.summary'>"
137 render_content
138 addn "</div>"
139 else
140 addn "<div class='col col-xs-12'>"
141 render_content
142 addn "</div>"
143 end
144 addn " </div>"
145 addn "</div>"
146 render_footer
147 end
148 end
149
150 # Top menu bar template.
151 #
152 # FIXME should be a Bootstrap component template
153 # At this moment, the topmenu structure stills to specific to Nitdoc to use the
154 # generic component.
155 class DocTopMenu
156 super UnorderedList
157
158 # Brand link to display in first position of the top menu.
159 #
160 # This is where you want to put your logo.
161 var brand: nullable Writable is noinit, writable
162
163 # Active menu item.
164 #
165 # Depends on the current page, this allows to hilighted the current item.
166 #
167 # FIXME should be using Boostrap breadcrumbs component.
168 # This will still like this to avoid diff and be changed in further fixes
169 # when we will modify the output.
170 var active_item: nullable ListItem is noinit, writable
171
172 redef fun rendering do
173 addn "<nav id='topmenu' class='navbar navbar-default navbar-fixed-top' role='navigation'>"
174 addn " <div class='container-fluid'>"
175 addn " <div class='navbar-header'>"
176 add " <button type='button' class='navbar-toggle' "
177 addn " data-toggle='collapse' data-target='#topmenu-collapse'>"
178 addn " <span class='sr-only'>Toggle menu</span>"
179 addn " <span class='icon-bar'></span>"
180 addn " <span class='icon-bar'></span>"
181 addn " <span class='icon-bar'></span>"
182 addn " </button>"
183 if brand != null then
184 add "<span class='navbar-brand'>"
185 add brand.write_to_string
186 add "</span>"
187 end
188 addn " </div>"
189 addn " <div class='collapse navbar-collapse' id='topmenu-collapse'>"
190 addn " <ul class='nav navbar-nav'>"
191 for item in items do
192 if item == active_item then item.css_classes.add "active"
193 add item.write_to_string
194 end
195 addn " </ul>"
196 addn " </div>"
197 addn " </div>"
198 addn "</nav>"
199 end
200 end
201
202 redef class DocComposite
203 super Template
204
205 # HTML anchor id
206 var html_id: String is noinit
207
208 # Title to display if any.
209 #
210 # This title can be decorated with HTML.
211 var html_title: nullable Writable is noinit, writable
212
213 # Subtitle to display if any.
214 var html_subtitle: nullable Writable is noinit, writable
215
216 # Render the element title and subtitle.
217 private fun render_title do
218 if html_title != null then
219 addn new Header(hlvl, html_title.write_to_string)
220 end
221 if html_subtitle != null then
222 addn "<div class='info subtitle'>"
223 addn html_subtitle.write_to_string
224 addn "</div>"
225 end
226 end
227
228 # Render the element body.
229 private fun render_body do end
230
231 redef fun rendering do
232 if is_hidden then return
233 render_title
234 render_body
235 end
236
237 # Level <hX> for HTML heading.
238 private fun hlvl: Int do
239 if parent == null then return 1
240 return parent.hlvl + 1
241 end
242
243 # Is `self` not displayed in the page.
244 #
245 # By default, empty elements are hidden.
246 fun is_hidden: Bool do return is_empty
247 end
248
249 redef class DocSection
250 super BSComponent
251
252 redef fun rendering do
253 if is_hidden then
254 addn "<a id=\"{html_id}\"></a>"
255 return
256 end
257 render_body
258 end
259 end
260
261 redef class DocArticle
262 super BSComponent
263
264 # Never displays the title for article.
265 #
266 # This is to maintain compatibility with old components, this may change
267 # without notice in further version.
268 redef fun render_title do end
269 end
270
271 redef class IntroArticle
272 redef var html_id is lazy do return "article_intro_{mentity.nitdoc_id}"
273 redef var html_title is lazy do return null
274 redef var is_hidden = false
275
276 redef fun render_body do
277 var comment = mentity.html_comment
278 if comment != null then addn comment
279 super
280 end
281 end
282
283 redef class ConcernsArticle
284 redef var html_id is lazy do return "article_concerns_{mentity.nitdoc_id}"
285 redef var html_title = "Concerns"
286 redef fun is_hidden do return concerns.is_empty
287
288 redef fun render_body do add concerns.html_list
289 end
290
291 redef class DefinitionArticle
292 redef var html_id is lazy do return "article_definition_{mentity.nitdoc_id}"
293 redef var html_title is lazy do return mentity.html_name
294 redef var html_subtitle is lazy do return mentity.html_declaration
295 redef var is_hidden = false
296
297 redef fun render_body do
298 var comment = mentity.html_comment
299 if comment != null then addn comment
300 super
301 end
302 end
303
304 redef class HierarchyListArticle
305 redef var html_id is lazy do return "article_hierarchy_{list_title}_{mentity.nitdoc_id}"
306 redef var html_title is lazy do return list_title
307 redef fun is_empty do return mentities.is_empty
308
309 redef fun render_body do
310 var lst = new UnorderedList
311 lst.css_classes.add "list-unstyled list-definition"
312 for mentity in mentities do
313 lst.add_li mentity.html_list_item
314 end
315 addn lst
316 end
317 end