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 #########################
27 # Top menu bar template
31 # Brand link to display in first position of the top menu
32 private var brand
: nullable Writable = null is writable
33 # Elements of the topmenu
34 private var elts
= new Array[Writable]
36 # The page url where the top menu is displayed.
38 # Used to select the active link.
39 private var current_url
: String
41 # Add a new link to the menu.
42 fun add_link
(content
: TplLink) do
43 var is_active
= content
.href
== current_url
44 add_item
(content
, is_active
)
47 # Add a content between `<li>` tags
48 fun add_item
(content
: Writable, is_active
: Bool) do
49 var tpl
= new Template
52 tpl
.add
" class=\"active\
""
60 # Add a raw content to the menu
61 fun add_raw
(content
: Writable) do
65 redef fun rendering
do
66 if brand
== null and elts
.is_empty
then return
67 addn
"<nav id='topmenu' class='navbar navbar-default navbar-fixed-top' role='navigation'>"
68 addn
" <div class='container-fluid'>"
69 addn
" <div class='navbar-header'>"
70 add
" <button type='button' class='navbar-toggle' "
71 addn
" data-toggle='collapse' data-target='#topmenu-collapse'>"
72 addn
" <span class='sr-only'>Toggle menu</span>"
73 addn
" <span class='icon-bar'></span>"
74 addn
" <span class='icon-bar'></span>"
75 addn
" <span class='icon-bar'></span>"
77 if brand
!= null then add brand
.as(not null)
79 addn
" <div class='collapse navbar-collapse' id='topmenu-collapse'>"
80 if not elts
.is_empty
then
81 addn
"<ul class='nav navbar-nav'>"
82 for elt
in elts
do add elt
95 # Sidebar contains sidebar element templates called boxes
96 var boxes
= new Array[TplSidebarElt]
98 # Sort boxes by order priority
99 private fun order_boxes
do
100 var sorter
= new OrderComparator
104 redef fun rendering
do
105 if boxes
.is_empty
then return
107 addn
"<div id='sidebar'>"
108 for box
in boxes
do add box
113 # Comparator used to sort boxes by order
114 private class OrderComparator
117 redef type COMPARED: TplSidebarElt
119 redef fun compare
(a
, b
) do
120 if a
.order
< b
.order
then return -1
121 if a
.order
> b
.order
then return 1
126 # Something that can be put in the sidebar
130 # Order of the box in the sidebar
133 init with_order
(order
: Int) do self.order
= order
136 # Agenericbox that can be added to sidebar
140 # Title of the box to display
141 # Title is also a placeholder for the collapse link
145 # equals to `title.to_cmangle` by default
146 # Used for collapsing
147 var id
: String is noinit
149 # Content to display in the box
150 # box will not be rendered if the content is null
151 var content
: nullable Writable = null is writable
153 # Is the box opened by default
154 # otherwise, the user will have to clic on the title to display the content
155 var is_open
= false is writable
158 self.id
= title
.to_cmangle
161 init with_content
(title
: String, content
: Writable) do
163 self.content
= content
166 redef fun rendering
do
167 if content
== null then return
169 if is_open
then open
= "in"
170 addn
"<div class='panel'>"
171 addn
" <div class='panel-heading'>"
172 add
" <a data-toggle='collapse' data-parent='#sidebar' data-target='#box_{id}' href='#'>"
176 addn
" <div id='box_{id}' class='panel-body collapse {open}'>"
177 add content
.as(not null)
183 # Something that can go on a summary template
187 # Add an element to the summary
188 fun add_child
(child
: TplSummaryElt) is abstract
191 # A summary that can go on the sidebar
192 # If the page contains a sidebar, the summary is automatically placed
193 # on top of the sidebarauto-generated
194 # summary contains anchors to all sections displayed in the page
199 # Summary elements to display
200 var children
= new Array[TplSummaryElt]
202 redef fun add_child
(child
) do children
.add child
204 redef fun rendering
do
205 if children
.is_empty
then return
206 addn
"<div class='panel'>"
207 addn
" <div class='panel-heading'>"
208 add
" <a data-toggle='collapse' data-parent='#sidebar' data-target='#box-sum' href='#'>"
212 addn
" <div id='box-sum' class='summary collapse in'>"
213 addn
" <ul class='nav'>"
214 for entry
in children
do add entry
222 class TplSummaryEntry
228 # Children of this entry
229 # Will be displayed as a tree
230 var children
= new Array[TplSummaryElt]
232 redef fun add_child
(child
) do children
.add child
234 redef fun rendering
do
237 if not children
.is_empty
then
238 addn
"\n<ul class='nav'>"
239 for entry
in children
do add entry
246 # Something that can go in a section
247 # Sections are automatically collected to populate the menu
254 # Title to display if any
255 # if both `title` and `summary_title` are null then
256 # the section will not appear in the summary
257 var title
: nullable Writable = null is writable
259 # Subtitle to display if any
260 var subtitle
: nullable Writable = null is writable
262 # Title that appear in the summary
263 # if null use `title` instead
264 var summary_title
: nullable String = null is writable
266 # CSS classes to apply on the section element
267 var css_classes
= new Array[String]
269 # CSS classes to apply on the title heading element
270 var title_classes
= new Array[String]
272 # Parent article/section if any
273 var parent
: nullable TplSectionElt = null
275 init with_title
(id
: String, title
: Writable) do
280 # Level <hX> for HTML heading
281 protected fun hlvl
: Int do
282 if parent
== null then return 1
283 return parent
.hlvl
+ 1
286 # Elements contained by this section
287 var children
= new Array[TplSectionElt]
289 # Add an element in this section
290 fun add_child
(child
: TplSectionElt) do
295 # Is the section empty (no content at all)
296 fun is_empty
: Bool do return children
.is_empty
298 # Render this section in the summary
299 fun render_summary
(parent
: TplSummaryElt) do
300 if is_empty
then return
301 var title
= summary_title
302 if title
== null and self.title
!= null then title
= self.title
.write_to_string
303 if title
== null then return
304 var lnk
= new TplLink("#{id}", title
)
305 var entry
= new TplSummaryEntry(lnk
)
306 for child
in children
do
307 child
.render_summary
(entry
)
309 parent
.add_child entry
313 # A HTML <section> element
317 redef fun rendering
do
318 addn
"<section id='{id}' class='{css_classes.join(" ")}'>"
319 if title
!= null then
321 if lvl
== 2 then title_classes
.add
"well well-sm"
322 addn
"<h{lvl} class='{title_classes.join(" ")}'>"
323 addn title
.as(not null)
326 if subtitle
!= null then
327 addn
"<div class='info subtitle'>"
328 addn subtitle
.as(not null)
331 for child
in children
do
338 # A page article that can go in a section
342 # Content for this article
343 var content
: nullable Writable = null is writable
344 var source_link
: nullable Writable = null is writable
346 init with_content
(id
: String, title
: Writable, content
: Writable) do
347 with_title
(id
, title
)
348 self.content
= content
351 redef fun render_summary
(parent
) do
352 if is_empty
then return
353 var title
= summary_title
354 if title
== null and self.title
!= null then title
= self.title
.write_to_string
355 if title
== null then return
356 var lnk
= new TplLink("#{id}", title
)
357 parent
.add_child
new TplSummaryEntry(lnk
)
360 redef fun rendering
do
361 if is_empty
then return
362 addn
"<article id='{id}' class='{css_classes.join(" ")}'>"
363 if source_link
!= null then
364 add
"<div class='source-link'>"
365 add source_link
.as(not null)
368 if title
!= null then
370 if lvl
== 2 then title_classes
.add
"well well-sm"
371 add
"<h{lvl} class='{title_classes.join(" ")}'>"
372 add title
.as(not null)
375 if subtitle
!= null then
376 add
"<div class='info subtitle'>"
377 add subtitle
.as(not null)
380 if content
!= null then
381 add content
.as(not null)
383 for child
in children
do
386 addn
"""</article>"""
389 redef fun is_empty
: Bool do
390 return title
== null and subtitle
== null and content
== null and children
.is_empty
394 # A module / class / prop definition
399 var comment
: nullable Writable = null is writable
401 # Namespace for this definition
402 var namespace
: nullable Writable = null is writable
404 # Location link to display
405 var location
: nullable Writable = null is writable
407 private fun render_info
do
408 addn
"<div class='info text-right'>"
409 if namespace
!= null then
410 if comment
== null then
411 add
"<span class=\"noComment\
">no comment for </span>"
413 add namespace
.as(not null)
415 if location
!= null then
417 add location
.as(not null)
422 private fun render_comment
do
423 if comment
!= null then add comment
.as(not null)
426 redef fun rendering
do
427 addn
"<div class='definition'>"
435 class TplClassDefinition
438 var intros
= new Array[TplListElt]
439 var redefs
= new Array[TplListElt]
441 redef fun rendering
do
442 addn
"<div class='definition'>"
445 render_list
("Introduces", intros
)
446 render_list
("Redefines", redefs
)
450 private fun render_list
(name
: String, elts
: Array[TplListElt]) do
451 if elts
.is_empty
then return
452 addn
"<h5>{name.html_escape}</h5>"
453 addn
"<ul class='list-unstyled list-definition'>"
454 for elt
in elts
do add elt
459 # Layout for Search page
463 var modules
= new Array[Writable]
464 var classes
= new Array[Writable]
465 var props
= new Array[Writable]
467 redef fun rendering
do
468 var title
= self.title
469 if title
!= null then addn
"<h1>{title.to_s.html_escape}</h1>"
470 addn
"<div class='container-fluid'>"
471 addn
" <div class='row'>"
472 if not modules
.is_empty
then
473 addn
"<div class='col-xs-4'>"
474 addn
"<h3>Modules</h3>"
484 if not classes
.is_empty
then
485 addn
"<div class='col-xs-4'>"
486 addn
"<h3>Classes</h3>"
496 if not props
.is_empty
then
497 addn
"<div class='col-xs-4'>"
498 addn
"<h3>Properties</h3>"
513 #####################
514 # Basiv HTML elements
515 #####################
522 var href
: String is writable
524 # The raw HTML content to display in the link
525 var text
: Writable is writable
527 # The unescaped optional title.
528 var title
: nullable String = null is writable
530 init with_title
(href
, text
, title
: String) do
535 redef fun rendering
do
539 if title
!= null then
541 add title.as(not null).html_escape
554 # Elements contained in this list
555 # can be <li> or <ul> elements
556 var elts
= new Array[TplListElt]
558 # CSS classes of the <ul> element
559 var css_classes
= new Array[String]
561 # Add content wrapped in a <li> element
562 fun add_li
(item
: TplListItem) do elts
.add item
564 init with_classes
(classes
: Array[String]) do self.css_classes
= classes
566 fun is_empty
: Bool do return elts
.is_empty
568 redef fun rendering
do
569 if elts
.is_empty
then return
570 addn
"<ul class='{css_classes.join(" ")}'>"
571 for elt
in elts
do add elt
576 # Something that can be added to a TplList
585 # Content of the list item
586 var content
= new Template
588 # CSS classes of the <li> element
589 var css_classes
= new Array[String]
591 init with_content
(content
: Writable) do append
(content
)
593 init with_classes
(content
: Writable, classes
: Array[String]) do
594 with_content
(content
)
595 css_classes
= classes
598 # Append `content` to the item
599 # similar to `self.content.add`
600 fun append
(content
: Writable) do self.content
.add content
602 redef fun rendering
do
603 add
"<li class='{css_classes.join(" ")}'>"
609 # A Bootstrap tab component that contains `TplTabPanel`.
613 # Panels contained in the tab.
614 var panels
= new Array[TplTabPanel]
617 fun add_panel
(panel
: TplTabPanel) do panels
.add panel
619 # CSS classes of the tab component.
620 var css_classes
= new Array[String]
622 redef fun rendering
do
623 addn
"<div class='tab-content'>"
624 for panel
in panels
do add panel
629 # A panel that goes in a `TplTab`.
633 # CSS classes of the pane element.
634 var css_classes
= new Array[String]
638 # Used to show/hide panel.
639 var id
: String is noinit
643 # Displayed in the tab header or in the pointing link.
646 # Is the panel visible by default?
647 var is_active
= false is writable
650 var content
: nullable Writable = null is writable
652 # Get a link pointing to this panel.
653 fun tpl_link_to
: Writable do
654 var lnk
= new Template
655 lnk
.add
"<a data-target='#{id}' data-toggle='pill'>"
661 redef fun rendering
do
662 add
"<div class='tab-pane {css_classes.join(" ")}"
663 if is_active
then add
"active"
665 if content
!= null then add content
.as(not null)
670 # A label with a text content
674 # Content of the label if any
675 var content
: nullable Writable = null is writable
677 # CSS classes of the <span> element
678 var css_classes
= new Array[String]
680 init with_content
(content
: Writable) do self.content
= content
681 init with_classes
(classes
: Array[String]) do self.css_classes
= classes
683 redef fun rendering
do
684 add
"<span class='label {css_classes.join(" ")}'>"
685 if content
!= null then add content
.as(not null)
690 # A label with an icon
695 # see: http://getbootstrap.com/components/#glyphicons
698 init with_icon
(icon
: String) do self.icon
= icon
700 redef fun rendering
do
701 add
"<span class='glyphicon glyphicon-{icon} {css_classes.join(" ")}'>"
702 if content
!= null then add content
.as(not null)
707 # A HTML tag attribute
708 # `<tag attr="value">`
711 # var attr: TagAttribute
713 # attr = new TagAttribute("foo", null)
714 # assert attr.write_to_string == " foo=\"\""
716 # attr = new TagAttribute("foo", "bar<>")
717 # assert attr.write_to_string == " foo=\"bar<>\""
723 var value
: nullable String
725 redef fun rendering
do
726 var value
= self.value
727 if value
== null then
728 # SEE: http://www.w3.org/TR/html5/infrastructure.html#boolean-attributes
729 add
" {name.html_escape}=\"\
""
731 add
" {name.html_escape}=\"{value.html_escape}\
""
740 var attrs
= new Array[TagAttribute]
741 var content
: nullable Writable = null is writable
744 attrs
.add
(new TagAttribute("type", "text/javascript"))
747 protected fun render_content
do
748 if content
!= null then add content
.as(not null)
751 redef fun rendering
do
753 for attr
in attrs
do add attr
760 # JS script for Piwik Tracker
764 var tracker_url
: String
767 redef fun render_content
do
768 var site_id
= self.site_id
.to_json
769 var tracker_url
= self.tracker_url
.trim
770 if tracker_url
.chars
.last
!= '/' then tracker_url
+= "/"
771 tracker_url
= "://{tracker_url}".to_json
773 addn
"<!-- Piwik -->"
774 addn
"var _paq = _paq || [];"
775 addn
" _paq.push([\"trackPageView\
"]);"
776 addn
" _paq.push([\"enableLinkTracking\
"]);"
777 addn
"(function() \{"
778 addn
" var u=((\"https
:\
" == document.location.protocol) ? \"https\
" : \"http\
") + {tracker_url};"
779 addn
" _paq.push([\"setTrackerUrl\
", u+\"piwik
.php\
"]);"
780 addn
" _paq.push([\"setSiteId\
", {site_id}]);"
781 addn
" var d=document, g=d.createElement(\"script\
"), s=d.getElementsByTagName(\"script\
")[0]; g.type=\"text
/javascript\
";"
782 addn
" g.defer=true; g.async=true; g.src=u+\"piwik
.js\
"; s.parentNode.insertBefore(g,s);"