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