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