module doc_templates
import template
+import json::static
# A documentation page
class TplPage
super Template
- # Page title in HTML header
- var title: String writable
+ # The unescaped page title to put in the HTML header.
+ var title: String is writable, noinit
+
+ # Page url
+ var url: String is writable, noinit
# Directory where css, js and other assets can be found
- var shareurl: String writable
+ var shareurl: String is writable, noinit
# Attributes of the body tag element
var body_attrs = new Array[TagAttribute]
# Top menu template if any
- var topmenu: TplTopMenu writable
+ var topmenu: TplTopMenu is writable, noinit
# Sidebar template if any
- var sidebar: nullable TplSidebar writable
+ var sidebar: nullable TplSidebar = null is writable
# Content of the page in form a TplSection
var sections = new Array[TplSection]
# Footer content if any
- var footer: nullable Streamable writable
+ var footer: nullable Writable = null is writable
# JS scripts to append at the end of the body
var scripts = new Array[TplScript]
- init do end
-
# Add a section to this page
fun add_section(section: TplSection) do
sections.add section
# Render the html header
private fun render_head do
- add "<!DOCTYPE html>"
- add "<head>"
- add " <meta charset='utf-8'/>"
- add " <!--link rel='stylesheet' href='{shareurl}/css/Nitdoc.UI.css' type='text/css'/-->"
- add " <link rel='stylesheet' href='{shareurl}/vendors/bootstrap/css/bootstrap.min.css'/>"
- add " <link rel='stylesheet' href='{shareurl}/css/nitdoc.bootstrap.css'/>"
- add " <link rel='stylesheet' href='{shareurl}/css/nitdoc.css'/>"
- add " <link rel='stylesheet' href='{shareurl}/css/Nitdoc.QuickSearch.css'/>"
- add " <link rel='stylesheet' href='{shareurl}/css/Nitdoc.ModalBox.css'/>"
- add " <link rel='stylesheet' href='{shareurl}/css/Nitdoc.GitHub.css'/>"
- add " <title>{title}</title>"
- add "</head>"
+ var css = (self.shareurl / "css").html_escape
+ var vendors = (self.shareurl / "vendors").html_escape
+
+ addn "<!DOCTYPE html>"
+ addn "<head>"
+ addn " <meta charset='utf-8'/>"
+ addn " <!--link rel='stylesheet' href='{css}/Nitdoc.UI.css' type='text/css'/-->"
+ addn " <link rel='stylesheet' href='{vendors}/bootstrap/css/bootstrap.min.css'/>"
+ addn " <link rel='stylesheet' href='{css}/nitdoc.bootstrap.css'/>"
+ addn " <link rel='stylesheet' href='{css}/nitdoc.css'/>"
+ addn " <link rel='stylesheet' href='{css}/Nitdoc.QuickSearch.css'/>"
+ addn " <link rel='stylesheet' href='{css}/Nitdoc.ModalBox.css'/>"
+ addn " <link rel='stylesheet' href='{css}/Nitdoc.GitHub.css'/>"
+ addn " <title>{title.html_escape}</title>"
+ addn "</head>"
add "<body"
for attr in body_attrs do add attr
- add ">"
+ addn ">"
end
# Render the topmenu template
private fun render_topmenu do
- add " <div class='row'>"
+ addn " <div class='row'>"
add topmenu
- add " </div>"
+ addn " </div>"
end
# Render the sidebar
private fun render_content do
for section in sections do add section
if footer != null then
- add "<div class='well footer'>"
+ addn "<div class='well footer'>"
add footer.as(not null)
- add "</div>"
+ addn "</div>"
end
end
# Render JS scripts
private fun render_footer do
- add "<script src='{shareurl}/vendors/jquery/jquery-1.11.1.min.js'></script>"
- add "<script src='{shareurl}/vendors/jquery/jquery-ui-1.10.4.custom.min.js'></script>"
- add "<script src='{shareurl}/vendors/bootstrap/js/bootstrap.min.js'></script>"
- add "<script data-main='{shareurl}/js/nitdoc' src='{shareurl}/js/lib/require.js'</script>"
+ var vendors = (self.shareurl / "vendors").html_escape
+ var js = (self.shareurl / "js").html_escape
+
+ addn "<script src='{vendors}/jquery/jquery-1.11.1.min.js'></script>"
+ addn "<script src='{vendors}/jquery/jquery-ui-1.10.4.custom.min.js'></script>"
+ addn "<script src='{vendors}/bootstrap/js/bootstrap.min.js'></script>"
+ addn "<script data-main='{js}/nitdoc' src='{js}/lib/require.js'></script>"
for script in scripts do add script
- add """<script>
+ addn """<script>
$(function () {
$("[data-toggle='tooltip']").tooltip();
$("[data-toggle='popover']").popover();
});
</script>"""
- add "</body>"
- add "</html>"
+ addn "</body>"
+ addn "</html>"
end
# Render the whole page
redef fun rendering do
render_head
- add "<div class='container-fluid'>"
+ addn "<div class='container-fluid'>"
render_topmenu
- add " <div class='row' id='content'>"
+ addn " <div class='row' id='content'>"
if sidebar != null then
- add "<div class='col col-xs-3 col-lg-2'>"
+ addn "<div class='col col-xs-3 col-lg-2'>"
render_sidebar
- add "</div>"
- add "<div class='col col-xs-9 col-lg-10' data-spy='scroll' data-target='.summary'>"
+ addn "</div>"
+ addn "<div class='col col-xs-9 col-lg-10' data-spy='scroll' data-target='.summary'>"
render_content
- add "</div>"
+ addn "</div>"
else
- add "<div class='col col-xs-12'>"
+ addn "<div class='col col-xs-12'>"
render_content
- add "</div>"
+ addn "</div>"
end
- add " </div>"
- add "</div>"
+ addn " </div>"
+ addn "</div>"
render_footer
end
end
class TplTopMenu
super Template
+ # Brand link to display in first position of the top menu
+ private var brand: nullable Writable = null is writable
# Elements of the topmenu
- private var elts = new Array[Streamable]
+ private var elts = new Array[Writable]
+
+ # The page url where the top menu is displayed.
+ #
+ # Used to select the active link.
+ private var current_url: String
- # Add a new link to the menu
- fun add_link(href, name: String, is_active: Bool) do
+ # Add a new link to the menu.
+ fun add_link(content: TplLink) do
+ var is_active = content.href == current_url
+ add_item(content, is_active)
+ end
+
+ # Add a content between `<li>` tags
+ fun add_item(content: Writable, is_active: Bool) do
var tpl = new Template
tpl.add "<li"
if is_active then
tpl.add " class='active'"
end
tpl.add ">"
- tpl.add new TplLink(href, name)
- tpl.add "</li>"
+ tpl.add content
+ tpl.addn "</li>"
add_raw(tpl)
end
# Add a raw content to the menu
- fun add_raw(content: Streamable) do
+ fun add_raw(content: Writable) do
elts.add content
end
redef fun rendering do
- add "<nav id='topmenu' class='navbar navbar-default navbar-fixed-top' role='navigation'>"
- add " <div class='container-fluid'>"
+ if brand == null and elts.is_empty then return
+ addn "<nav id='topmenu' class='navbar navbar-default navbar-fixed-top' role='navigation'>"
+ addn " <div class='container-fluid'>"
+ addn " <div class='navbar-header'>"
+ add " <button type='button' class='navbar-toggle' "
+ addn " data-toggle='collapse' data-target='#topmenu-collapse'>"
+ addn " <span class='sr-only'>Toggle menu</span>"
+ addn " <span class='icon-bar'></span>"
+ addn " <span class='icon-bar'></span>"
+ addn " <span class='icon-bar'></span>"
+ addn " </button>"
+ if brand != null then add brand.as(not null)
+ addn " </div>"
+ addn " <div class='collapse navbar-collapse' id='topmenu-collapse'>"
if not elts.is_empty then
- add "<ul class='nav navbar-nav'>"
- for elt in elts do add(elt)
- add "</ul>"
+ addn "<ul class='nav navbar-nav'>"
+ for elt in elts do add elt
+ addn "</ul>"
end
- add " </div>"
- add "</nav>"
+ addn " </div>"
+ addn " </div>"
+ addn "</nav>"
end
end
redef fun rendering do
if boxes.is_empty then return
order_boxes
- add "<div id='sidebar'>"
+ addn "<div id='sidebar'>"
for box in boxes do add box
- add "</div>"
+ addn "</div>"
end
end
# Comparator used to sort boxes by order
private class OrderComparator
- super Comparator[TplSidebarElt]
+ super Comparator
+
+ redef type COMPARED: TplSidebarElt
redef fun compare(a, b) do
if a.order < b.order then return -1
# Box HTML id
# equals to `title.to_cmangle` by default
# Used for collapsing
- var id: String
+ var id: String is noinit
# Content to display in the box
# box will not be rendered if the content is null
- var content: nullable Streamable writable
+ var content: nullable Writable = null is writable
# Is the box opened by default
# otherwise, the user will have to clic on the title to display the content
- var is_open writable = false
+ var is_open = false is writable
- init(title: String) do
- self.title = title
+ init do
self.id = title.to_cmangle
end
- init with_content(title: String, content: Streamable) do
+ init with_content(title: String, content: Writable) do
init(title)
self.content = content
end
if content == null then return
var open = ""
if is_open then open = "in"
- add "<div class='panel'>"
- add " <div class='panel-heading'>"
+ addn "<div class='panel'>"
+ addn " <div class='panel-heading'>"
add " <a data-toggle='collapse' data-parent='#sidebar' data-target='#box_{id}' href='#'>"
add title
- add " </a>"
- add " </div>"
- add " <div id='box_{id}' class='panel-body collapse {open}'>"
+ addn " </a>"
+ addn " </div>"
+ addn " <div id='box_{id}' class='panel-body collapse {open}'>"
add content.as(not null)
- add " </div>"
- add "</div>"
+ addn " </div>"
+ addn "</div>"
end
end
redef fun rendering do
if children.is_empty then return
- add "<div class='panel'>"
- add " <div class='panel-heading'>"
+ addn "<div class='panel'>"
+ addn " <div class='panel-heading'>"
add " <a data-toggle='collapse' data-parent='#sidebar' data-target='#box-sum' href='#'>"
add "Summary"
- add " </a>"
- add " </div>"
- add " <div id='box-sum' class='summary collapse in'>"
- add " <ul class='nav'>"
+ addn " </a>"
+ addn " </div>"
+ addn " <div id='box-sum' class='summary collapse in'>"
+ addn " <ul class='nav'>"
for entry in children do add entry
- add " </ul>"
- add " </div>"
- add "</div>"
+ addn " </ul>"
+ addn " </div>"
+ addn "</div>"
end
end
super TplSummaryElt
# Text to display
- var text: Streamable
+ var text: Writable
# Children of this entry
# Will be displayed as a tree
var children = new Array[TplSummaryElt]
- init(text: Streamable) do self.text = text
-
redef fun add_child(child) do children.add child
redef fun rendering do
add "<li>"
add text
if not children.is_empty then
- add "<ul class='nav'>"
+ addn "\n<ul class='nav'>"
for entry in children do add entry
- add "</ul>"
+ addn "</ul>"
end
- add "</li>"
+ addn "</li>"
end
end
# Title to display if any
# if both `title` and `summary_title` are null then
# the section will not appear in the summary
- var title: nullable Streamable writable
+ var title: nullable Writable = null is writable
# Subtitle to display if any
- var subtitle: nullable Streamable writable
+ var subtitle: nullable Writable = null is writable
# Title that appear in the summary
# if null use `title` instead
- var summary_title: nullable String writable
+ var summary_title: nullable String = null is writable
+
+ # CSS classes to apply on the section element
+ var css_classes = new Array[String]
- # Parent section of this section if any
- var parent: nullable TplSection
+ # CSS classes to apply on the title heading element
+ var title_classes = new Array[String]
- init(id: String) do self.id = id
+ # Parent article/section if any
+ var parent: nullable TplSectionElt = null
- init with_title(id: String, title: Streamable) do
+ init with_title(id: String, title: Writable) do
init(id)
self.title = title
end
return parent.hlvl + 1
end
- # Render this section in the summary
- protected fun render_summary(parent: TplSummaryElt) is abstract
-
- # Is the section empty (no content at all)
- fun is_empty: Bool is abstract
-end
-
-# A HTML <section> element
-class TplSection
- super TplSectionElt
-
# Elements contained by this section
var children = new Array[TplSectionElt]
children.add child
end
- redef fun is_empty: Bool do return children.is_empty
+ # Is the section empty (no content at all)
+ fun is_empty: Bool do return children.is_empty
- redef fun render_summary(parent) do
+ # Render this section in the summary
+ fun render_summary(parent: TplSummaryElt) do
if is_empty then return
var title = summary_title
if title == null and self.title != null then title = self.title.write_to_string
end
parent.add_child entry
end
+end
+
+# A HTML <section> element
+class TplSection
+ super TplSectionElt
redef fun rendering do
- if is_empty then return
- add "<section id='{id}'>"
+ addn "<section id='{id}' class='{css_classes.join(" ")}'>"
if title != null then
var lvl = hlvl
- add "<h{lvl}>"
- add title.as(not null)
- add "</h{lvl}>"
+ if lvl == 2 then title_classes.add "well well-sm"
+ addn "<h{lvl} class='{title_classes.join(" ")}'>"
+ addn title.as(not null)
+ addn "</h{lvl}>"
end
if subtitle != null then
- add "<div class='info subtitle'>"
- add subtitle.as(not null)
- add "</div>"
+ addn "<div class='info subtitle'>"
+ addn subtitle.as(not null)
+ addn "</div>"
end
for child in children do
add child
end
- add "</section>"
+ addn "</section>"
end
end
super TplSectionElt
# Content for this article
- var content: nullable Streamable writable = null
+ var content: nullable Writable = null is writable
+ var source_link: nullable Writable = null is writable
- # CSS classes to apply on the article title heading element
- var title_classes = new Array[String]
+ init with_content(id: String, title: Writable, content: Writable) do
+ with_title(id, title)
+ self.content = content
+ end
redef fun render_summary(parent) do
if is_empty then return
end
redef fun rendering do
- add "<article id='{id}'>"
+ if is_empty then return
+ addn "<article id='{id}' class='{css_classes.join(" ")}'>"
+ if source_link != null then
+ add "<div class='source-link'>"
+ add source_link.as(not null)
+ addn "</div>"
+ end
if title != null then
var lvl = hlvl
+ if lvl == 2 then title_classes.add "well well-sm"
add "<h{lvl} class='{title_classes.join(" ")}'>"
add title.as(not null)
- add "</h{lvl}>"
+ addn "</h{lvl}>"
end
if subtitle != null then
add "<div class='info subtitle'>"
add subtitle.as(not null)
- add "</div>"
+ addn "</div>"
end
if content != null then
add content.as(not null)
end
- add """</article>"""
+ for child in children do
+ add child
+ end
+ addn """</article>"""
end
- redef fun is_empty: Bool do return content == null
+ redef fun is_empty: Bool do
+ return title == null and subtitle == null and content == null and children.is_empty
+ end
end
# A module / class / prop definition
super Template
# Comment to display
- var comment: nullable Streamable writable
+ var comment: nullable Writable = null is writable
# Namespace for this definition
- var namespace: Streamable writable
+ var namespace: nullable Writable = null is writable
# Location link to display
- var location: nullable Streamable writable
-
- init do end
+ var location: nullable Writable = null is writable
private fun render_info do
- add "<div class='info text-right'>"
- if comment == null then
- add "<span class=\"noComment\">no comment for </span>"
+ addn "<div class='info text-right'>"
+ if namespace != null then
+ if comment == null then
+ add "<span class=\"noComment\">no comment for </span>"
+ end
+ add namespace.as(not null)
end
- add namespace
if location != null then
add " "
add location.as(not null)
end
- add "</div>"
+ addn "</div>"
end
private fun render_comment do
end
redef fun rendering do
- add "<div class='definition'>"
+ addn "<div class='definition'>"
render_comment
render_info
- add "</div>"
+ addn "</div>"
end
end
var intros = new Array[TplListElt]
var redefs = new Array[TplListElt]
- init do end
-
redef fun rendering do
- add "<div class='definition'>"
+ addn "<div class='definition'>"
render_comment
render_info
render_list("Introduces", intros)
render_list("Redefines", redefs)
- add "</div>"
+ addn "</div>"
end
private fun render_list(name: String, elts: Array[TplListElt]) do
if elts.is_empty then return
- add "<h5>{name}</h5>"
- add "<ul class='list-unstyled list-definition'>"
+ addn "<h5>{name.html_escape}</h5>"
+ addn "<ul class='list-unstyled list-definition'>"
for elt in elts do add elt
- add "</ul>"
+ addn "</ul>"
end
end
class TplSearchPage
super TplSectionElt
- var modules = new Array[Streamable]
- var classes = new Array[Streamable]
- var props = new Array[Streamable]
+ var modules = new Array[Writable]
+ var classes = new Array[Writable]
+ var props = new Array[Writable]
redef fun rendering do
var title = self.title
- if title != null then add "<h1>{title}</h1>"
- add "<div class='container-fluid'>"
- add " <div class='row'>"
+ if title != null then addn "<h1>{title.to_s.html_escape}</h1>"
+ addn "<div class='container-fluid'>"
+ addn " <div class='row'>"
if not modules.is_empty then
- add "<div class='col-xs-4'>"
- add "<h3>Modules</h3>"
- add "<ul>"
+ addn "<div class='col-xs-4'>"
+ addn "<h3>Modules</h3>"
+ addn "<ul>"
for m in modules do
add "<li>"
add m
- add "</li>"
+ addn "</li>"
end
- add "</ul>"
- add "</div>"
+ addn "</ul>"
+ addn "</div>"
end
if not classes.is_empty then
- add "<div class='col-xs-4'>"
- add "<h3>Classes</h3>"
- add "<ul>"
+ addn "<div class='col-xs-4'>"
+ addn "<h3>Classes</h3>"
+ addn "<ul>"
for c in classes do
add "<li>"
add c
- add "</li>"
+ addn "</li>"
end
- add "</ul>"
- add "</div>"
+ addn "</ul>"
+ addn "</div>"
end
if not props.is_empty then
- add "<div class='col-xs-4'>"
- add "<h3>Properties</h3>"
- add "<ul>"
+ addn "<div class='col-xs-4'>"
+ addn "<h3>Properties</h3>"
+ addn "<ul>"
for p in props do
add "<li>"
add p
- add "</li>"
+ addn "</li>"
end
- add "</ul>"
- add "</div>"
+ addn "</ul>"
+ addn "</div>"
end
- add " </div>"
- add "</div>"
+ addn " </div>"
+ addn "</div>"
end
end
super Template
# Link href
- var href: String writable
-
- # Text to display in the link
- var text: String writable
+ var href: String is writable
- # Optional title
- var title: nullable String writable
+ # The raw HTML content to display in the link
+ var text: Writable is writable
- init(href, text: String) do
- self.href = href
- self.text = text
- end
+ # The unescaped optional title.
+ var title: nullable String = null is writable
init with_title(href, text, title: String) do
init(href, text)
redef fun rendering do
add "<a href=\""
- add href
+ add href.html_escape
add "\""
if title != null then
add " title=\""
- add title.as(not null)
+ add title.as(not null).html_escape
add "\""
end
add ">"
var css_classes = new Array[String]
# Add content wrapped in a <li> element
- fun add_li(content: Streamable) do elts.add new TplListItem.with_content(content)
-
- init do end
+ fun add_li(item: TplListItem) do elts.add item
init with_classes(classes: Array[String]) do self.css_classes = classes
+ fun is_empty: Bool do return elts.is_empty
+
redef fun rendering do
if elts.is_empty then return
- add "<ul class='{css_classes.join(" ")}'>"
+ addn "<ul class='{css_classes.join(" ")}'>"
for elt in elts do add elt
- add "</ul>"
+ addn "</ul>"
end
end
# CSS classes of the <li> element
var css_classes = new Array[String]
- init do end
+ init with_content(content: Writable) do append(content)
- init with_content(content: Streamable) do append(content)
-
- init with_classes(content: Streamable, classes: Array[String]) do
+ init with_classes(content: Writable, classes: Array[String]) do
with_content(content)
css_classes = classes
end
# Append `content` to the item
# similar to `self.content.add`
- fun append(content: Streamable) do self.content.add content
+ fun append(content: Writable) do self.content.add content
redef fun rendering do
- add "<li class='"
- for cls in css_classes do add " {cls}"
- add "'>"
+ add "<li class='{css_classes.join(" ")}'>"
add content
- add "</li>"
+ addn "</li>"
+ end
+end
+
+# A Bootstrap tab component that contains `TplTabPanel`.
+class TplTab
+ super Template
+
+ # Panels contained in the tab.
+ var panels = new Array[TplTabPanel]
+
+ # Add a new panel.
+ fun add_panel(panel: TplTabPanel) do panels.add panel
+
+ # CSS classes of the tab component.
+ var css_classes = new Array[String]
+
+ redef fun rendering do
+ addn "<div class='tab-content'>"
+ for panel in panels do add panel
+ addn "</div>"
+ end
+end
+
+# A panel that goes in a `TplTab`.
+class TplTabPanel
+ super Template
+
+ # CSS classes of the pane element.
+ var css_classes = new Array[String]
+
+ # The panel id.
+ #
+ # Used to show/hide panel.
+ var id: String is noinit
+
+ # The panel name.
+ #
+ # Displayed in the tab header or in the pointing link.
+ var name: Writable
+
+ # Is the panel visible by default?
+ var is_active = false is writable
+
+ # Body of the panel
+ var content: nullable Writable = null is writable
+
+ # Get a link pointing to this panel.
+ fun tpl_link_to: Writable do
+ var lnk = new Template
+ lnk.add "<a data-target='#{id}' data-toggle='pill'>"
+ lnk.add name
+ lnk.add "</a>"
+ return lnk
+ end
+
+ redef fun rendering do
+ add "<div class='tab-pane {css_classes.join(" ")}"
+ if is_active then add "active"
+ addn "' id='{id}'>"
+ if content != null then add content.as(not null)
+ addn "</div>"
end
end
super Template
# Content of the label if any
- var content: nullable Streamable
+ var content: nullable Writable = null is writable
# CSS classes of the <span> element
var css_classes = new Array[String]
- init do end
- init with_content(content: Streamable) do self.content = content
+ init with_content(content: Writable) do self.content = content
init with_classes(classes: Array[String]) do self.css_classes = classes
redef fun rendering do
# A HTML tag attribute
# `<tag attr="value">`
+#
+# ~~~nit
+# var attr: TagAttribute
+#
+# attr = new TagAttribute("foo", null)
+# assert attr.write_to_string == " foo=\"\""
+#
+# attr = new TagAttribute("foo", "bar<>")
+# assert attr.write_to_string == " foo=\"bar<>\""
+# ~~~
class TagAttribute
super Template
var name: String
var value: nullable String
- init(name: String, value: nullable String) do
- self.name = name
- self.value = value
- end
-
redef fun rendering do
var value = self.value
if value == null then
- add(" {name}")
+ # SEE: http://www.w3.org/TR/html5/infrastructure.html#boolean-attributes
+ add " {name.html_escape}=\"\""
else
- add(" {name}=\"{value}\"")
+ add " {name.html_escape}=\"{value.html_escape}\""
end
end
end
super Template
var attrs = new Array[TagAttribute]
- var content: nullable Streamable writable
+ var content: nullable Writable = null is writable
init do
attrs.add(new TagAttribute("type", "text/javascript"))
redef fun rendering do
add "<script"
for attr in attrs do add attr
- add ">"
+ addn ">"
render_content
- add "</script>"
+ addn "</script>"
end
end
var tracker_url: String
var site_id: String
- init(tracker_url, site_id: String) do
- super
- self.tracker_url = tracker_url
- self.site_id = site_id
- end
-
redef fun render_content do
- add "<!-- Piwik -->"
- add "var _paq = _paq || [];"
- add " _paq.push([\"trackPageView\"]);"
- add " _paq.push([\"enableLinkTracking\"]);"
- add "(function() \{"
- add " var u=((\"https:\" == document.location.protocol) ? \"https\" : \"http\") + \"://{tracker_url}\";"
- add " _paq.push([\"setTrackerUrl\", u+\"piwik.php\"]);"
- add " _paq.push([\"setSiteId\", \"{site_id}\"]);"
- add " var d=document, g=d.createElement(\"script\"), s=d.getElementsByTagName(\"script\")[0]; g.type=\"text/javascript\";"
- add " g.defer=true; g.async=true; g.src=u+\"piwik.js\"; s.parentNode.insertBefore(g,s);"
- add "\})();"
+ var site_id = self.site_id.to_json
+ var tracker_url = self.tracker_url.trim
+ if tracker_url.chars.last != '/' then tracker_url += "/"
+ tracker_url = "://{tracker_url}".to_json
+
+ addn "<!-- Piwik -->"
+ addn "var _paq = _paq || [];"
+ addn " _paq.push([\"trackPageView\"]);"
+ addn " _paq.push([\"enableLinkTracking\"]);"
+ addn "(function() \{"
+ addn " var u=((\"https:\" == document.location.protocol) ? \"https\" : \"http\") + {tracker_url};"
+ addn " _paq.push([\"setTrackerUrl\", u+\"piwik.php\"]);"
+ addn " _paq.push([\"setSiteId\", {site_id}]);"
+ addn " var d=document, g=d.createElement(\"script\"), s=d.getElementsByTagName(\"script\")[0]; g.type=\"text/javascript\";"
+ addn " g.defer=true; g.async=true; g.src=u+\"piwik.js\"; s.parentNode.insertBefore(g,s);"
+ addn "\})();"
end
end