0e8f00b17141766e069ea8ba2f6d2507b8c513cd
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`
21 # A documentation page
25 # Page title in HTML header
26 var title
: String is writable, noinit
29 var url
: String is writable, noinit
31 # Directory where css, js and other assets can be found
32 var shareurl
: String is writable, noinit
34 # Attributes of the body tag element
35 var body_attrs
= new Array[TagAttribute]
37 # Top menu template if any
38 var topmenu
: TplTopMenu is writable, noinit
40 # Sidebar template if any
41 var sidebar
: nullable TplSidebar = null is writable
43 # Content of the page in form a TplSection
44 var sections
= new Array[TplSection]
46 # Footer content if any
47 var footer
: nullable Streamable = null is writable
49 # JS scripts to append at the end of the body
50 var scripts
= new Array[TplScript]
52 # Add a section to this page
53 fun add_section
(section
: TplSection) do
57 # Render the html header
58 private fun render_head
do
61 add
" <meta charset='utf-8'/>"
62 add
" <!--link rel='stylesheet' href='{shareurl}/css/Nitdoc.UI.css' type='text/css'/-->"
63 add
" <link rel='stylesheet' href='{shareurl}/vendors/bootstrap/css/bootstrap.min.css'/>"
64 add
" <link rel='stylesheet' href='{shareurl}/css/nitdoc.bootstrap.css'/>"
65 add
" <link rel='stylesheet' href='{shareurl}/css/nitdoc.css'/>"
66 add
" <link rel='stylesheet' href='{shareurl}/css/Nitdoc.QuickSearch.css'/>"
67 add
" <link rel='stylesheet' href='{shareurl}/css/Nitdoc.ModalBox.css'/>"
68 add
" <link rel='stylesheet' href='{shareurl}/css/Nitdoc.GitHub.css'/>"
69 add
" <title>{title}</title>"
72 for attr
in body_attrs
do add attr
76 # Render the topmenu template
77 private fun render_topmenu
do
78 add
" <div class='row'>"
84 # Sidebar is automatically populated with a summary of all sections
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
91 sidebar
.boxes
.add summary
92 add sidebar
.as(not null)
94 # Render the footer and content
95 private fun render_content
do
96 for section
in sections
do add section
97 if footer
!= null then
98 add
"<div class='well footer'>"
99 add footer
.as(not null)
105 private fun render_footer
do
106 add
"<script src='{shareurl}/vendors/jquery/jquery-1.11.1.min.js'></script>"
107 add
"<script src='{shareurl}/vendors/jquery/jquery-ui-1.10.4.custom.min.js'></script>"
108 add
"<script src='{shareurl}/vendors/bootstrap/js/bootstrap.min.js'></script>"
109 add
"<script data-main='{shareurl}/js/nitdoc' src='{shareurl}/js/lib/require.js'></script>"
110 for script
in scripts
do add script
113 $("[data-toggle='tooltip']").tooltip();
114 $("[data-toggle='popover']").popover();
121 # Render the whole page
122 redef fun rendering
do
124 add
"<div class='container-fluid'>"
126 add
" <div class='row' id='content'>"
127 if sidebar
!= null then
128 add
"<div class='col col-xs-3 col-lg-2'>"
131 add
"<div class='col col-xs-9 col-lg-10' data-spy='scroll' data-target='.summary'>"
135 add
"<div class='col col-xs-12'>"
145 #########################
146 # general layout elements
147 #########################
149 # Top menu bar template
153 # Brand link to display in first position of the top menu
154 private var brand
: nullable Streamable = null is writable
155 # Elements of the topmenu
156 private var elts
= new Array[Streamable]
158 # The page url where the top menu is displayed.
160 # Used to select the active link.
161 private var current_url
: String
163 # Add a new link to the menu.
164 fun add_link
(content
: TplLink) do
165 var is_active
= content
.href
== current_url
166 add_item
(content
, is_active
)
169 # Add a content between `<li>` tags
170 fun add_item
(content
: Streamable, is_active
: Bool) do
171 var tpl
= new Template
174 tpl
.add
" class='active'"
182 # Add a raw content to the menu
183 fun add_raw
(content
: Streamable) do
187 redef fun rendering
do
188 if brand
== null and elts
.is_empty
then return
189 add
"<nav id='topmenu' class='navbar navbar-default navbar-fixed-top' role='navigation'>"
190 add
" <div class='container-fluid'>"
191 add
" <div class='navbar-header'>"
192 add
" <button type='button' class='navbar-toggle' "
193 add
" data-toggle='collapse' data-target='#topmenu-collapse'>"
194 add
" <span class='sr-only'>Toggle menu</span>"
195 add
" <span class='icon-bar'></span>"
196 add
" <span class='icon-bar'></span>"
197 add
" <span class='icon-bar'></span>"
199 if brand
!= null then add brand
.as(not null)
201 add
" <div class='collapse navbar-collapse' id='topmenu-collapse'>"
202 if not elts
.is_empty
then
203 add
"<ul class='nav navbar-nav'>"
204 for elt
in elts
do add elt
217 # Sidebar contains sidebar element templates called boxes
218 var boxes
= new Array[TplSidebarElt]
220 # Sort boxes by order priority
221 private fun order_boxes
do
222 var sorter
= new OrderComparator
226 redef fun rendering
do
227 if boxes
.is_empty
then return
229 add
"<div id='sidebar'>"
230 for box
in boxes
do add box
235 # Comparator used to sort boxes by order
236 private class OrderComparator
239 redef type COMPARED: TplSidebarElt
241 redef fun compare
(a
, b
) do
242 if a
.order
< b
.order
then return -1
243 if a
.order
> b
.order
then return 1
248 # Something that can be put in the sidebar
252 # Order of the box in the sidebar
255 init with_order
(order
: Int) do self.order
= order
258 # Agenericbox that can be added to sidebar
262 # Title of the box to display
263 # Title is also a placeholder for the collapse link
267 # equals to `title.to_cmangle` by default
268 # Used for collapsing
269 var id
: String is noinit
271 # Content to display in the box
272 # box will not be rendered if the content is null
273 var content
: nullable Streamable = null is writable
275 # Is the box opened by default
276 # otherwise, the user will have to clic on the title to display the content
277 var is_open
= false is writable
280 self.id
= title
.to_cmangle
283 init with_content
(title
: String, content
: Streamable) do
285 self.content
= content
288 redef fun rendering
do
289 if content
== null then return
291 if is_open
then open
= "in"
292 add
"<div class='panel'>"
293 add
" <div class='panel-heading'>"
294 add
" <a data-toggle='collapse' data-parent='#sidebar' data-target='#box_{id}' href='#'>"
298 add
" <div id='box_{id}' class='panel-body collapse {open}'>"
299 add content
.as(not null)
305 # Something that can go on a summary template
309 # Add an element to the summary
310 fun add_child
(child
: TplSummaryElt) is abstract
313 # A summary that can go on the sidebar
314 # If the page contains a sidebar, the summary is automatically placed
315 # on top of the sidebarauto-generated
316 # summary contains anchors to all sections displayed in the page
321 # Summary elements to display
322 var children
= new Array[TplSummaryElt]
324 redef fun add_child
(child
) do children
.add child
326 redef fun rendering
do
327 if children
.is_empty
then return
328 add
"<div class='panel'>"
329 add
" <div class='panel-heading'>"
330 add
" <a data-toggle='collapse' data-parent='#sidebar' data-target='#box-sum' href='#'>"
334 add
" <div id='box-sum' class='summary collapse in'>"
335 add
" <ul class='nav'>"
336 for entry
in children
do add entry
344 class TplSummaryEntry
350 # Children of this entry
351 # Will be displayed as a tree
352 var children
= new Array[TplSummaryElt]
354 redef fun add_child
(child
) do children
.add child
356 redef fun rendering
do
359 if not children
.is_empty
then
360 add
"<ul class='nav'>"
361 for entry
in children
do add entry
368 # Something that can go in a section
369 # Sections are automatically collected to populate the menu
376 # Title to display if any
377 # if both `title` and `summary_title` are null then
378 # the section will not appear in the summary
379 var title
: nullable Streamable = null is writable
381 # Subtitle to display if any
382 var subtitle
: nullable Streamable = null is writable
384 # Title that appear in the summary
385 # if null use `title` instead
386 var summary_title
: nullable String = null is writable
388 # CSS classes to apply on the section element
389 var css_classes
= new Array[String]
391 # CSS classes to apply on the title heading element
392 var title_classes
= new Array[String]
394 # Parent article/section if any
395 var parent
: nullable TplSectionElt = null
397 init with_title
(id
: String, title
: Streamable) do
402 # Level <hX> for HTML heading
403 protected fun hlvl
: Int do
404 if parent
== null then return 1
405 return parent
.hlvl
+ 1
408 # Elements contained by this section
409 var children
= new Array[TplSectionElt]
411 # Add an element in this section
412 fun add_child
(child
: TplSectionElt) do
417 # Is the section empty (no content at all)
418 fun is_empty
: Bool do return children
.is_empty
420 # Render this section in the summary
421 fun render_summary
(parent
: TplSummaryElt) do
422 if is_empty
then return
423 var title
= summary_title
424 if title
== null and self.title
!= null then title
= self.title
.write_to_string
425 if title
== null then return
426 var lnk
= new TplLink("#{id}", title
)
427 var entry
= new TplSummaryEntry(lnk
)
428 for child
in children
do
429 child
.render_summary
(entry
)
431 parent
.add_child entry
435 # A HTML <section> element
439 redef fun rendering
do
440 add
"<section id='{id}' class='{css_classes.join(" ")}'>"
441 if title
!= null then
443 if lvl
== 2 then title_classes
.add
"well well-sm"
444 add
"<h{lvl} class='{title_classes.join(" ")}'>"
445 add title
.as(not null)
448 if subtitle
!= null then
449 add
"<div class='info subtitle'>"
450 add subtitle
.as(not null)
453 for child
in children
do
460 # A page article that can go in a section
464 # Content for this article
465 var content
: nullable Streamable = null is writable
466 var source_link
: nullable Streamable = null is writable
468 init with_content
(id
: String, title
: Streamable, content
: Streamable) do
469 with_title
(id
, title
)
470 self.content
= content
473 redef fun render_summary
(parent
) do
474 if is_empty
then return
475 var title
= summary_title
476 if title
== null and self.title
!= null then title
= self.title
.write_to_string
477 if title
== null then return
478 var lnk
= new TplLink("#{id}", title
)
479 parent
.add_child
new TplSummaryEntry(lnk
)
482 redef fun rendering
do
483 if is_empty
then return
484 add
"<article id='{id}' class='{css_classes.join(" ")}'>"
485 if source_link
!= null then
486 add
"<div class='source-link'>"
487 add source_link
.as(not null)
490 if title
!= null then
492 if lvl
== 2 then title_classes
.add
"well well-sm"
493 add
"<h{lvl} class='{title_classes.join(" ")}'>"
494 add title
.as(not null)
497 if subtitle
!= null then
498 add
"<div class='info subtitle'>"
499 add subtitle
.as(not null)
502 if content
!= null then
503 add content
.as(not null)
505 for child
in children
do
511 redef fun is_empty
: Bool do
512 return title
== null and subtitle
== null and content
== null and children
.is_empty
516 # A module / class / prop definition
521 var comment
: nullable Streamable = null is writable
523 # Namespace for this definition
524 var namespace
: nullable Streamable = null is writable
526 # Location link to display
527 var location
: nullable Streamable = null is writable
529 private fun render_info
do
530 add
"<div class='info text-right'>"
531 if namespace
!= null then
532 if comment
== null then
533 add
"<span class=\"noComment\
">no comment for </span>"
535 add namespace
.as(not null)
537 if location
!= null then
539 add location
.as(not null)
544 private fun render_comment
do
545 if comment
!= null then add comment
.as(not null)
548 redef fun rendering
do
549 add
"<div class='definition'>"
557 class TplClassDefinition
560 var intros
= new Array[TplListElt]
561 var redefs
= new Array[TplListElt]
565 redef fun rendering
do
566 add
"<div class='definition'>"
569 render_list
("Introduces", intros
)
570 render_list
("Redefines", redefs
)
574 private fun render_list
(name
: String, elts
: Array[TplListElt]) do
575 if elts
.is_empty
then return
576 add
"<h5>{name}</h5>"
577 add
"<ul class='list-unstyled list-definition'>"
578 for elt
in elts
do add elt
583 # Layout for Search page
587 var modules
= new Array[Streamable]
588 var classes
= new Array[Streamable]
589 var props
= new Array[Streamable]
591 redef fun rendering
do
592 var title
= self.title
593 if title
!= null then add
"<h1>{title}</h1>"
594 add
"<div class='container-fluid'>"
595 add
" <div class='row'>"
596 if not modules
.is_empty
then
597 add
"<div class='col-xs-4'>"
598 add
"<h3>Modules</h3>"
608 if not classes
.is_empty
then
609 add
"<div class='col-xs-4'>"
610 add
"<h3>Classes</h3>"
620 if not props
.is_empty
then
621 add
"<div class='col-xs-4'>"
622 add
"<h3>Properties</h3>"
637 #####################
638 # Basiv HTML elements
639 #####################
646 var href
: String is writable
648 # Text to display in the link
649 var text
: Streamable is writable
652 var title
: nullable String = null is writable
654 init with_title
(href
, text
, title
: String) do
659 redef fun rendering
do
663 if title
!= null then
665 add title.as(not null)
678 # Elements contained in this list
679 # can be <li> or <ul> elements
680 var elts
= new Array[TplListElt]
682 # CSS classes of the <ul> element
683 var css_classes
= new Array[String]
685 # Add content wrapped in a <li> element
686 fun add_li
(item
: TplListItem) do elts
.add item
690 init with_classes
(classes
: Array[String]) do self.css_classes
= classes
692 fun is_empty
: Bool do return elts
.is_empty
694 redef fun rendering
do
695 if elts
.is_empty
then return
696 add
"<ul class='{css_classes.join(" ")}'>"
697 for elt
in elts
do add elt
702 # Something that can be added to a TplList
711 # Content of the list item
712 var content
= new Template
714 # CSS classes of the <li> element
715 var css_classes
= new Array[String]
719 init with_content
(content
: Streamable) do append
(content
)
721 init with_classes
(content
: Streamable, classes
: Array[String]) do
722 with_content
(content
)
723 css_classes
= classes
726 # Append `content` to the item
727 # similar to `self.content.add`
728 fun append
(content
: Streamable) do self.content
.add content
730 redef fun rendering
do
731 add
"<li class='{css_classes.join(" ")}'>"
737 # A Bootstrap tab component that contains `TplTabPanel`.
741 # Panels contained in the tab.
742 var panels
= new Array[TplTabPanel]
745 fun add_panel
(panel
: TplTabPanel) do panels
.add panel
747 # CSS classes of the tab component.
748 var css_classes
= new Array[String]
750 redef fun rendering
do
751 add
"<div class='tab-content'>"
752 for panel
in panels
do add panel
757 # A panel that goes in a `TplTab`.
761 # CSS classes of the pane element.
762 var css_classes
= new Array[String]
766 # Used to show/hide panel.
767 var id
: String is noinit
771 # Displayed in the tab header or in the pointing link.
774 # Is the panel visible by default?
775 var is_active
= false is writable
778 var content
: nullable Streamable = null is writable
780 # Get a link pointing to this panel.
781 fun tpl_link_to
: Streamable do
782 var lnk
= new Template
783 lnk
.add
"<a data-target='#{id}' data-toggle='pill'>"
789 redef fun rendering
do
790 add
"<div class='tab-pane {css_classes.join(" ")}"
791 if is_active
then add
"active"
793 if content
!= null then add content
.as(not null)
798 # A label with a text content
802 # Content of the label if any
803 var content
: nullable Streamable = null is writable
805 # CSS classes of the <span> element
806 var css_classes
= new Array[String]
808 init with_content
(content
: Streamable) do self.content
= content
809 init with_classes
(classes
: Array[String]) do self.css_classes
= classes
811 redef fun rendering
do
812 add
"<span class='label {css_classes.join(" ")}'>"
813 if content
!= null then add content
.as(not null)
818 # A label with an icon
823 # see: http://getbootstrap.com/components/#glyphicons
826 init with_icon
(icon
: String) do self.icon
= icon
828 redef fun rendering
do
829 add
"<span class='glyphicon glyphicon-{icon} {css_classes.join(" ")}'>"
830 if content
!= null then add content
.as(not null)
835 # A HTML tag attribute
836 # `<tag attr="value">`
841 var value
: nullable String
843 redef fun rendering
do
844 var value
= self.value
845 if value
== null then
848 add
(" {name}=\"{value}\
"")
857 var attrs
= new Array[TagAttribute]
858 var content
: nullable Streamable = null is writable
861 attrs
.add
(new TagAttribute("type", "text/javascript"))
864 protected fun render_content
do
865 if content
!= null then add content
.as(not null)
868 redef fun rendering
do
870 for attr
in attrs
do add attr
877 # JS script for Piwik Tracker
881 var tracker_url
: String
884 redef fun render_content
do
886 add
"var _paq = _paq || [];"
887 add
" _paq.push([\"trackPageView\
"]);"
888 add
" _paq.push([\"enableLinkTracking\
"]);"
890 add
" var u=((\"https
:\
" == document.location.protocol) ? \"https\
" : \"http\
") + \"://{tracker_url}\
";"
891 add
" _paq.push([\"setTrackerUrl\
", u+\"piwik
.php\
"]);"
892 add
" _paq.push([\"setSiteId\
", \"{site_id}\
"]);"
893 add
" var d=document, g=d.createElement(\"script\
"), s=d.getElementsByTagName(\"script\
")[0]; g.type=\"text
/javascript\
";"
894 add
" g.defer=true; g.async=true; g.src=u+\"piwik
.js\
"; s.parentNode.insertBefore(g,s);"