1 # This file is part of NIT ( http://www.nitlanguage.org ).
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
7 # http://www.apache.org/licenses/LICENSE-2.0
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.
15 # HTML templates used by Nitdoc to generate API documentation
16 # Pages are assembled using `Template`
17 module html_components
23 #########################
24 # general layout elements
25 #########################
31 # Sidebar contains sidebar element templates called boxes
32 var boxes
= new Array[TplSidebarElt]
34 # Sort boxes by order priority
35 private fun order_boxes
do
36 var sorter
= new OrderComparator
40 redef fun rendering
do
41 if boxes
.is_empty
then return
43 addn
"<div id='sidebar'>"
44 for box
in boxes
do add box
49 # Comparator used to sort boxes by order
50 private class OrderComparator
53 redef type COMPARED: TplSidebarElt
55 redef fun compare
(a
, b
) do
56 if a
.order
< b
.order
then return -1
57 if a
.order
> b
.order
then return 1
62 # Something that can be put in the sidebar
66 # Order of the box in the sidebar
69 init with_order
(order
: Int) do self.order
= order
72 # Agenericbox that can be added to sidebar
76 # Title of the box to display
77 # Title is also a placeholder for the collapse link
81 # equals to `title.to_cmangle` by default
83 var id
: String is noinit
85 # Content to display in the box
86 # box will not be rendered if the content is null
87 var content
: nullable Writable = null is writable
89 # Is the box opened by default
90 # otherwise, the user will have to clic on the title to display the content
91 var is_open
= false is writable
94 self.id
= title
.to_cmangle
97 init with_content
(title
: String, content
: Writable) do
99 self.content
= content
102 redef fun rendering
do
103 if content
== null then return
105 if is_open
then open
= "in"
106 addn
"<div class='panel'>"
107 addn
" <div class='panel-heading'>"
108 add
" <a data-toggle='collapse' data-parent='#sidebar' data-target='#box_{id}' href='#'>"
112 addn
" <div id='box_{id}' class='panel-body collapse {open}'>"
113 add content
.as(not null)
119 # Something that can go on a summary template
123 # Add an element to the summary
124 fun add_child
(child
: TplSummaryElt) is abstract
127 # A summary that can go on the sidebar
128 # If the page contains a sidebar, the summary is automatically placed
129 # on top of the sidebarauto-generated
130 # summary contains anchors to all sections displayed in the page
135 # Summary elements to display
136 var children
= new Array[TplSummaryElt]
138 redef fun add_child
(child
) do children
.add child
140 redef fun rendering
do
141 if children
.is_empty
then return
142 addn
"<div class='panel'>"
143 addn
" <div class='panel-heading'>"
144 add
" <a data-toggle='collapse' data-parent='#sidebar' data-target='#box-sum' href='#'>"
148 addn
" <div id='box-sum' class='summary collapse in'>"
149 addn
" <ul class='nav'>"
150 for entry
in children
do add entry
158 class TplSummaryEntry
164 # Children of this entry
165 # Will be displayed as a tree
166 var children
= new Array[TplSummaryElt]
168 redef fun add_child
(child
) do children
.add child
170 redef fun rendering
do
173 if not children
.is_empty
then
174 addn
"\n<ul class='nav'>"
175 for entry
in children
do add entry
182 # Something that can go in a section
183 # Sections are automatically collected to populate the menu
190 # Title to display if any
191 # if both `title` and `summary_title` are null then
192 # the section will not appear in the summary
193 var title
: nullable Writable = null is writable
195 # Subtitle to display if any
196 var subtitle
: nullable Writable = null is writable
198 # Title that appear in the summary
199 # if null use `title` instead
200 var summary_title
: nullable String = null is writable
202 # CSS classes to apply on the section element
203 var css_classes
= new Array[String]
205 # CSS classes to apply on the title heading element
206 var title_classes
= new Array[String]
208 # Parent article/section if any
209 var parent
: nullable TplSectionElt = null
211 init with_title
(id
: String, title
: Writable) do
216 # Level <hX> for HTML heading
217 protected fun hlvl
: Int do
218 if parent
== null then return 1
219 return parent
.hlvl
+ 1
222 # Elements contained by this section
223 var children
= new Array[TplSectionElt]
225 # Add an element in this section
226 fun add_child
(child
: TplSectionElt) do
231 # Is the section empty (no content at all)
232 fun is_empty
: Bool do return children
.is_empty
234 # Render this section in the summary
235 fun render_summary
(parent
: TplSummaryElt) do
236 if is_empty
then return
237 var title
= summary_title
238 if title
== null and self.title
!= null then title
= self.title
.write_to_string
239 if title
== null then return
240 var lnk
= new TplLink("#{id}", title
)
241 var entry
= new TplSummaryEntry(lnk
)
242 for child
in children
do
243 child
.render_summary
(entry
)
245 parent
.add_child entry
249 # A HTML <section> element
253 redef fun rendering
do
254 addn
"<section id='{id}' class='{css_classes.join(" ")}'>"
255 if title
!= null then
257 if lvl
== 2 then title_classes
.add
"well well-sm"
258 addn
"<h{lvl} class='{title_classes.join(" ")}'>"
259 addn title
.as(not null)
262 if subtitle
!= null then
263 addn
"<div class='info subtitle'>"
264 addn subtitle
.as(not null)
267 for child
in children
do
274 # A page article that can go in a section
278 # Content for this article
279 var content
: nullable Writable = null is writable
280 var source_link
: nullable Writable = null is writable
282 init with_content
(id
: String, title
: Writable, content
: Writable) do
283 with_title
(id
, title
)
284 self.content
= content
287 redef fun render_summary
(parent
) do
288 if is_empty
then return
289 var title
= summary_title
290 if title
== null and self.title
!= null then title
= self.title
.write_to_string
291 if title
== null then return
292 var lnk
= new TplLink("#{id}", title
)
293 parent
.add_child
new TplSummaryEntry(lnk
)
296 redef fun rendering
do
297 if is_empty
then return
298 addn
"<article id='{id}' class='{css_classes.join(" ")}'>"
299 if source_link
!= null then
300 add
"<div class='source-link'>"
301 add source_link
.as(not null)
304 if title
!= null then
306 if lvl
== 2 then title_classes
.add
"well well-sm"
307 add
"<h{lvl} class='{title_classes.join(" ")}'>"
308 add title
.as(not null)
311 if subtitle
!= null then
312 add
"<div class='info subtitle'>"
313 add subtitle
.as(not null)
316 if content
!= null then
317 add content
.as(not null)
319 for child
in children
do
322 addn
"""</article>"""
325 redef fun is_empty
: Bool do
326 return title
== null and subtitle
== null and content
== null and children
.is_empty
330 # A module / class / prop definition
335 var comment
: nullable Writable = null is writable
337 # Namespace for this definition
338 var namespace
: nullable Writable = null is writable
340 # Location link to display
341 var location
: nullable Writable = null is writable
343 private fun render_info
do
344 addn
"<div class='info text-right'>"
345 if namespace
!= null then
346 if comment
== null then
347 add
"<span class=\"noComment\
">no comment for </span>"
349 add namespace
.as(not null)
351 if location
!= null then
353 add location
.as(not null)
358 private fun render_comment
do
359 if comment
!= null then add comment
.as(not null)
362 redef fun rendering
do
363 addn
"<div class='definition'>"
371 class TplClassDefinition
374 var intros
= new Array[TplListElt]
375 var redefs
= new Array[TplListElt]
377 redef fun rendering
do
378 addn
"<div class='definition'>"
381 render_list
("Introduces", intros
)
382 render_list
("Redefines", redefs
)
386 private fun render_list
(name
: String, elts
: Array[TplListElt]) do
387 if elts
.is_empty
then return
388 addn
"<h5>{name.html_escape}</h5>"
389 addn
"<ul class='list-unstyled list-definition'>"
390 for elt
in elts
do add elt
395 # Layout for Search page
399 var modules
= new Array[Writable]
400 var classes
= new Array[Writable]
401 var props
= new Array[Writable]
403 redef fun rendering
do
404 var title
= self.title
405 if title
!= null then addn
"<h1>{title.to_s.html_escape}</h1>"
406 addn
"<div class='container-fluid'>"
407 addn
" <div class='row'>"
408 if not modules
.is_empty
then
409 addn
"<div class='col-xs-4'>"
410 addn
"<h3>Modules</h3>"
420 if not classes
.is_empty
then
421 addn
"<div class='col-xs-4'>"
422 addn
"<h3>Classes</h3>"
432 if not props
.is_empty
then
433 addn
"<div class='col-xs-4'>"
434 addn
"<h3>Properties</h3>"
449 #####################
450 # Basiv HTML elements
451 #####################
458 var href
: String is writable
460 # The raw HTML content to display in the link
461 var text
: Writable is writable
463 # The unescaped optional title.
464 var title
: nullable String = null is writable
466 init with_title
(href
, text
, title
: String) do
471 redef fun rendering
do
475 if title
!= null then
477 add title.as(not null).html_escape
490 # Elements contained in this list
491 # can be <li> or <ul> elements
492 var elts
= new Array[TplListElt]
494 # CSS classes of the <ul> element
495 var css_classes
= new Array[String]
497 # Add content wrapped in a <li> element
498 fun add_li
(item
: TplListItem) do elts
.add item
500 init with_classes
(classes
: Array[String]) do self.css_classes
= classes
502 fun is_empty
: Bool do return elts
.is_empty
504 redef fun rendering
do
505 if elts
.is_empty
then return
506 addn
"<ul class='{css_classes.join(" ")}'>"
507 for elt
in elts
do add elt
512 # Something that can be added to a TplList
521 # Content of the list item
522 var content
= new Template
524 # CSS classes of the <li> element
525 var css_classes
= new Array[String]
527 init with_content
(content
: Writable) do append
(content
)
529 init with_classes
(content
: Writable, classes
: Array[String]) do
530 with_content
(content
)
531 css_classes
= classes
534 # Append `content` to the item
535 # similar to `self.content.add`
536 fun append
(content
: Writable) do self.content
.add content
538 redef fun rendering
do
539 add
"<li class='{css_classes.join(" ")}'>"
545 # A Bootstrap tab component that contains `TplTabPanel`.
549 # Panels contained in the tab.
550 var panels
= new Array[TplTabPanel]
553 fun add_panel
(panel
: TplTabPanel) do panels
.add panel
555 # CSS classes of the tab component.
556 var css_classes
= new Array[String]
558 redef fun rendering
do
559 addn
"<div class='tab-content'>"
560 for panel
in panels
do add panel
565 # A panel that goes in a `TplTab`.
569 # CSS classes of the pane element.
570 var css_classes
= new Array[String]
574 # Used to show/hide panel.
575 var id
: String is noinit
579 # Displayed in the tab header or in the pointing link.
582 # Is the panel visible by default?
583 var is_active
= false is writable
586 var content
: nullable Writable = null is writable
588 # Get a link pointing to this panel.
589 fun tpl_link_to
: Writable do
590 var lnk
= new Template
591 lnk
.add
"<a data-target='#{id}' data-toggle='pill'>"
597 redef fun rendering
do
598 add
"<div class='tab-pane {css_classes.join(" ")}"
599 if is_active
then add
"active"
601 if content
!= null then add content
.as(not null)
606 # A label with a text content
610 # Content of the label if any
611 var content
: nullable Writable = null is writable
613 # CSS classes of the <span> element
614 var css_classes
= new Array[String]
616 init with_content
(content
: Writable) do self.content
= content
617 init with_classes
(classes
: Array[String]) do self.css_classes
= classes
619 redef fun rendering
do
620 add
"<span class='label {css_classes.join(" ")}'>"
621 if content
!= null then add content
.as(not null)
626 # A label with an icon
631 # see: http://getbootstrap.com/components/#glyphicons
634 init with_icon
(icon
: String) do self.icon
= icon
636 redef fun rendering
do
637 add
"<span class='glyphicon glyphicon-{icon} {css_classes.join(" ")}'>"
638 if content
!= null then add content
.as(not null)
643 # A HTML tag attribute
644 # `<tag attr="value">`
647 # var attr: TagAttribute
649 # attr = new TagAttribute("foo", null)
650 # assert attr.write_to_string == " foo=\"\""
652 # attr = new TagAttribute("foo", "bar<>")
653 # assert attr.write_to_string == " foo=\"bar<>\""
659 var value
: nullable String
661 redef fun rendering
do
662 var value
= self.value
663 if value
== null then
664 # SEE: http://www.w3.org/TR/html5/infrastructure.html#boolean-attributes
665 add
" {name.html_escape}=\"\
""
667 add
" {name.html_escape}=\"{value.html_escape}\
""
676 var attrs
= new Array[TagAttribute]
677 var content
: nullable Writable = null is writable
680 attrs
.add
(new TagAttribute("type", "text/javascript"))
683 protected fun render_content
do
684 if content
!= null then add content
.as(not null)
687 redef fun rendering
do
689 for attr
in attrs
do add attr
696 # JS script for Piwik Tracker
700 var tracker_url
: String
703 redef fun render_content
do
704 var site_id
= self.site_id
.to_json
705 var tracker_url
= self.tracker_url
.trim
706 if tracker_url
.chars
.last
!= '/' then tracker_url
+= "/"
707 tracker_url
= "://{tracker_url}".to_json
709 addn
"<!-- Piwik -->"
710 addn
"var _paq = _paq || [];"
711 addn
" _paq.push([\"trackPageView\
"]);"
712 addn
" _paq.push([\"enableLinkTracking\
"]);"
713 addn
"(function() \{"
714 addn
" var u=((\"https
:\
" == document.location.protocol) ? \"https\
" : \"http\
") + {tracker_url};"
715 addn
" _paq.push([\"setTrackerUrl\
", u+\"piwik
.php\
"]);"
716 addn
" _paq.push([\"setSiteId\
", {site_id}]);"
717 addn
" var d=document, g=d.createElement(\"script\
"), s=d.getElementsByTagName(\"script\
")[0]; g.type=\"text
/javascript\
";"
718 addn
" g.defer=true; g.async=true; g.src=u+\"piwik
.js\
"; s.parentNode.insertBefore(g,s);"