Templates are simple hierarchical pieces of text used for efficient stream writing.

Efficient stream writing

Templates are more efficient than ever-growing buffers with useless concatenation and more usable and maintainable than manual arrays of strings.

The add method (and its variations) is used to append new content (like string or other templates) to a template object.

Eventually, the write_to method (and its variations) is used to write the complete content of a template in streams (and files, and strings).

var tmpl = new Template
tmpl.add("A")
tmpl.add("B")
tmpl.add("C")
assert tmpl.write_to_string == "ABC"

Non-linear system with sub-templates.

A template is made of a mix of string, sub-templates and other Writable objects. A sub-template can be constructed independently of its usages, thus simplifying the high-level logic. A single sub-template can be used more than once.

var main = new Template
var sub = new Template
sub.add("1")
main.add("A")
main.add(sub)
main.add("B")
main.add(sub)
main.add("C")
sub.add("2")
assert main.write_to_string == "A12B12C"

See also the new_sub method.

Specific high-level templates

The advanced, and recommended way, is to subclass Template and provide an autonomous structural template with its specific attributes and templating logic.

In such a subclass, the full logic is provided by the rendering method that will be automatically and lazily invoked.

class LnkTmpl
    super Template
    var text: Writable
    var title: nullable String
    var href: String
    redef fun rendering do
        add """<a href="{{{href.html_escape}}}""""
        if title != null then add """ title="{{{title.html_escape}}}""""
        add ">"
        add text
        add "</a>"
    end
    # ...
end
var l = new LnkTmpl("hello world", null, "hello.png")
assert l.write_to_string == """<a href="hello.png">hello world</a>"""

Introduced properties

private var _content: Array[Writable]

template :: Template :: _content

Each sub-elements
private var _is_frozen: Bool

template :: Template :: _is_frozen

Is the template allowing more modification (add)
private var _is_writing: Bool

template :: Template :: _is_writing

Flag to avoid infinite recursivity if a template contains itself
private var _render_done: Bool

template :: Template :: _render_done

Flag to avoid multiple rendering
fun add(element: Writable)

template :: Template :: add

Append an element (String, other Template, etc.) at the end of the template.
fun add_all(elements: Collection[Writable])

template :: Template :: add_all

Append a bunch of elements at the end of the template.
fun add_list(elements: Collection[Writable], sep: Writable, last_sep: Writable)

template :: Template :: add_list

Append a bunch of elements at the end of the template with separations.
fun addn(element: Writable)

template :: Template :: addn

Append element and the end of the template then append a "\n".
private fun content: Array[Writable]

template :: Template :: content

Each sub-elements
private fun content=(content: Array[Writable])

template :: Template :: content=

Each sub-elements
fun force_render

template :: Template :: force_render

Call rendering, if not already done
fun freeze

template :: Template :: freeze

Disable further modification: no more add is allowed
fun is_frozen: Bool

template :: Template :: is_frozen

Is the template allowing more modification (add)
protected fun is_frozen=(is_frozen: Bool)

template :: Template :: is_frozen=

Is the template allowing more modification (add)
private fun is_writing: Bool

template :: Template :: is_writing

Flag to avoid infinite recursivity if a template contains itself
private fun is_writing=(is_writing: Bool)

template :: Template :: is_writing=

Flag to avoid infinite recursivity if a template contains itself
fun new_sub: Template

template :: Template :: new_sub

Return a new basic template that is automatically added in self (using add)
private fun render_done: Bool

template :: Template :: render_done

Flag to avoid multiple rendering
private fun render_done=(render_done: Bool)

template :: Template :: render_done=

Flag to avoid multiple rendering
protected fun rendering

template :: Template :: rendering

Service used to render the content of the template.

Redefined properties

redef type SELF: Template

template $ Template :: SELF

Type of this instance, automatically specialized in every class
redef fun write_to(stream: Writer)

template $ Template :: write_to

Do the full rendering and write the final content to a stream

All properties

fun !=(other: nullable Object): Bool

core :: Object :: !=

Have self and other different values?
fun ==(other: nullable Object): Bool

core :: Object :: ==

Have self and other the same value?
type CLASS: Class[SELF]

core :: Object :: CLASS

The type of the class of self.
type SELF: Object

core :: Object :: SELF

Type of this instance, automatically specialized in every class
private var _content: Array[Writable]

template :: Template :: _content

Each sub-elements
private var _is_frozen: Bool

template :: Template :: _is_frozen

Is the template allowing more modification (add)
private var _is_writing: Bool

template :: Template :: _is_writing

Flag to avoid infinite recursivity if a template contains itself
private var _render_done: Bool

template :: Template :: _render_done

Flag to avoid multiple rendering
fun add(element: Writable)

template :: Template :: add

Append an element (String, other Template, etc.) at the end of the template.
fun add_all(elements: Collection[Writable])

template :: Template :: add_all

Append a bunch of elements at the end of the template.
fun add_list(elements: Collection[Writable], sep: Writable, last_sep: Writable)

template :: Template :: add_list

Append a bunch of elements at the end of the template with separations.
fun addn(element: Writable)

template :: Template :: addn

Append element and the end of the template then append a "\n".
protected fun class_factory(name: String): CLASS

core :: Object :: class_factory

Implementation used by get_class to create the specific class.
fun class_name: String

core :: Object :: class_name

The class name of the object.
private fun content: Array[Writable]

template :: Template :: content

Each sub-elements
private fun content=(content: Array[Writable])

template :: Template :: content=

Each sub-elements
fun force_render

template :: Template :: force_render

Call rendering, if not already done
fun freeze

template :: Template :: freeze

Disable further modification: no more add is allowed
fun get_class: CLASS

core :: Object :: get_class

The meta-object representing the dynamic type of self.
fun hash: Int

core :: Object :: hash

The hash code of the object.
init init

core :: Object :: init

fun inspect: String

core :: Object :: inspect

Developer readable representation of self.
protected fun inspect_head: String

core :: Object :: inspect_head

Return "CLASSNAME:#OBJECTID".
fun is_frozen: Bool

template :: Template :: is_frozen

Is the template allowing more modification (add)
protected fun is_frozen=(is_frozen: Bool)

template :: Template :: is_frozen=

Is the template allowing more modification (add)
intern fun is_same_instance(other: nullable Object): Bool

core :: Object :: is_same_instance

Return true if self and other are the same instance (i.e. same identity).
fun is_same_serialized(other: nullable Object): Bool

core :: Object :: is_same_serialized

Is self the same as other in a serialization context?
intern fun is_same_type(other: Object): Bool

core :: Object :: is_same_type

Return true if self and other have the same dynamic type.
private fun is_writing: Bool

template :: Template :: is_writing

Flag to avoid infinite recursivity if a template contains itself
private fun is_writing=(is_writing: Bool)

template :: Template :: is_writing=

Flag to avoid infinite recursivity if a template contains itself
private intern fun native_class_name: CString

core :: Object :: native_class_name

The class name of the object in CString format.
fun new_sub: Template

template :: Template :: new_sub

Return a new basic template that is automatically added in self (using add)
intern fun object_id: Int

core :: Object :: object_id

An internal hash code for the object based on its identity.
fun output

core :: Object :: output

Display self on stdout (debug only).
intern fun output_class_name

core :: Object :: output_class_name

Display class name on stdout (debug only).
private fun render_done: Bool

template :: Template :: render_done

Flag to avoid multiple rendering
private fun render_done=(render_done: Bool)

template :: Template :: render_done=

Flag to avoid multiple rendering
protected fun rendering

template :: Template :: rendering

Service used to render the content of the template.
fun serialization_hash: Int

core :: Object :: serialization_hash

Hash value use for serialization
intern fun sys: Sys

core :: Object :: sys

Return the global sys object, the only instance of the Sys class.
abstract fun to_jvalue(env: JniEnv): JValue

core :: Object :: to_jvalue

fun to_s: String

core :: Object :: to_s

User readable representation of self.
abstract fun write_to(stream: Writer)

core :: Writable :: write_to

Write itself to a stream
fun write_to_bytes: Bytes

core :: Writable :: write_to_bytes

Like write_to but return a new Bytes (may be quite large)
fun write_to_file(filepath: String)

core :: Writable :: write_to_file

Like write_to but take care of creating the file
fun write_to_string: String

core :: Writable :: write_to_string

Like write_to but return a new String (may be quite large).
package_diagram template::Template Template core::Writable Writable template::Template->core::Writable core::Object Object core::Writable->core::Object ...core::Object ... ...core::Object->core::Object template::Template... ... template::Template...->template::Template

Ancestors

interface Object

core :: Object

The root of the class hierarchy.

Parents

interface Writable

core :: Writable

Things that can be efficienlty written to a Writer

Children

abstract class BSComponent

html :: BSComponent

Bootstrap component abstraction.
class BashCompletion

nitc :: BashCompletion

This class generates a compatible bash_completion script file.
class CatalogPage

nitc :: CatalogPage

A HTML page in a catalog
class DocPage

nitc :: DocPage

A documentation page abstraction
class DocSidebar

nitc :: DocSidebar

Nitdoc sidebar abstraction
class DocTab

nitc :: DocTab

A documentation tabulated view
class ErrorTemplate

nitcorn :: ErrorTemplate

A basic error page for the HTTP error code
class JavaClassTemplate

nitc :: JavaClassTemplate

Java class source template
class LaunchScreenStoryboardTemplate

nitc :: LaunchScreenStoryboardTemplate

Template for the loading screen to generate LaunchScreen.storyboard
class NitModule

gen_nit :: NitModule

Template of a Nit module to generate Nit code
class PbxprojectTemplate

nitc :: PbxprojectTemplate

Template for a PBX project file, usually a project.pbcproj
class PiwikScript

nitc :: PiwikScript

JS script for Piwik Tracker
class PlistTemplate

nitc :: PlistTemplate

Template for a property list used by XCode for iOS projects
abstract class StaticCard

nitc :: StaticCard

A card that can be rendered to HTML
private class TemplateMacro

template :: TemplateMacro

A macro is a special text command that is replaced by other content in a TemplateString.
class TemplateString

template :: TemplateString

Template with macros replacement.
class TmplComposer

template :: TmplComposer

A composer in the short list of composers
class TmplComposerDetail

template :: TmplComposerDetail

A composer in the detailled list of composers
class TmplComposers

template :: TmplComposers

The root template for composers

Descendants

class BSAlert

html :: BSAlert

A Bootstrap alert component.
class BSBadge

html :: BSBadge

A Bootstrap badge component.
class BSBreadCrumbs

html :: BSBreadCrumbs

A Bootstrap breadcrumbs component.
class BSIcon

html :: BSIcon

A Boostrap icon.
class BSLabel

html :: BSLabel

A Bootstrap label component.
class BSPageHeader

html :: BSPageHeader

A Bootstrap page header component.
class BSPanel

html :: BSPanel

A Bootstrap panel component.
abstract class CardCatalog

nitc :: CardCatalog

A card that displays Nit catalog related data
class CardCatalogPackage

nitc :: CardCatalogPackage

A card that displays a package from a Nit catalog
class CardCatalogStats

nitc :: CardCatalogStats

A card that displays statistics about a Nit catalog
class CardCatalogTags

nitc :: CardCatalogTags

A card that displays a list of tags
class CardCode

nitc :: CardCode

A card that displays the code of a MEntity
class CardGraph

nitc :: CardGraph

A card that displays a graph
class CardInheritance

nitc :: CardInheritance

A card about the inheritance of a MEntity
class CardLinearizationDef

nitc :: CardLinearizationDef

A card about a definition in a linearization list
class CardLinearizationList

nitc :: CardLinearizationList

A card about the linearization of a MEntity
class CardList

nitc :: CardList

A list of cards
class CardMDoc

nitc :: CardMDoc

A card that displays the content of a MDoc
class CardMEntity

nitc :: CardMEntity

A card about a mentity
class CardMdSummary

nitc :: CardMdSummary

A card that displays the summary of a Markdown document
class CardMetadata

nitc :: CardMetadata

A card that displays the metadata about a package in the Nit catalog
class CardPageHeader

nitc :: CardPageHeader

A page header
class CardSection

nitc :: CardSection

A heading section
class CardSummary

nitc :: CardSummary

A card that displays a summary of a list of cards
class CardText

nitc :: CardText

A card that display custom text data
class DocTopMenu

nitc :: DocTopMenu

Top menu bar template
abstract class HTMLList

html :: HTMLList

An abstract HTML list.
class Header

html :: Header

A <h1> to <h6> tag.
class ListItem

html :: ListItem

A <li> tag.
class OrderedList

html :: OrderedList

A <ol> list tag.
class PageHome

nitc :: PageHome

The Nitdoc overview page that displays the nit packages catalog
class PageMClass

nitc :: PageMClass

A documentation page about a MClass
abstract class PageMEntity

nitc :: PageMEntity

A DocPage documenting a MEntity
class PageMGroup

nitc :: PageMGroup

A documentation page about a MGroup
class PageMModule

nitc :: PageMModule

A documentation page about a MModule
class PageMPackage

nitc :: PageMPackage

A documentation page for a MPackage
class PageMProperty

nitc :: PageMProperty

A documentation page about a MProperty
class PagePerson

nitc :: PagePerson

A page that lists the packages maintained and contributed by a person
class PageTag

nitc :: PageTag

A page that lists the packages related to a tab
class UnorderedList

html :: UnorderedList

A <ul> list tag.

Class definitions

template $ Template
# Templates are simple hierarchical pieces of text used for efficient stream writing.
#
# # Efficient stream writing
#
# Templates are more efficient than ever-growing buffers with useless concatenation
# and more usable and maintainable than manual arrays of strings.
#
# The `add` method (and its variations) is used to append new content (like string or
# other templates) to a template object.
#
# Eventually, the `write_to` method (and its variations) is used to write the complete
# content of a template in streams (and files, and strings).
#
#     var tmpl = new Template
#     tmpl.add("A")
#     tmpl.add("B")
#     tmpl.add("C")
#     assert tmpl.write_to_string == "ABC"
#
# # Non-linear system with sub-templates.
#
# A template is made of a mix of string, sub-templates and other `Writable` objects.
# A sub-template can be constructed independently of its usages, thus simplifying
# the high-level logic.
# A single sub-template can be used more than once.
#
#     var main = new Template
#     var sub = new Template
#     sub.add("1")
#     main.add("A")
#     main.add(sub)
#     main.add("B")
#     main.add(sub)
#     main.add("C")
#     sub.add("2")
#     assert main.write_to_string == "A12B12C"
#
# See also the `new_sub` method.
#
# # Specific high-level templates
#
# The advanced, and recommended way, is to subclass Template and provide an autonomous
# structural template with its specific attributes and templating logic.
#
# In such a subclass, the full logic is provided by the `rendering` method that will
# be automatically and lazily invoked.
#
#     class LnkTmpl
#         super Template
#         var text: Writable
#         var title: nullable String
#         var href: String
#         redef fun rendering do
#             add """<a href="{{{href.html_escape}}}""""
#             if title != null then add """ title="{{{title.html_escape}}}""""
#             add ">"
#             add text
#             add "</a>"
#         end
#         # ...
#     end
#     var l = new LnkTmpl("hello world", null, "hello.png")
#     assert l.write_to_string == """<a href="hello.png">hello world</a>"""
#
class Template
	super Writable

	# Service used to render the content of the template.
	#
	# Do nothing by default but subclasses should put all their specific
	# templating code in this method to regroup and simplify their logic
	#
	# Note: to avoid inconsistencies, the template is automatically frozen
	# (see `freeze`) after the invocation of `rendering`.
	protected fun rendering do end

	# Append an element (`String`, other `Template`, etc.) at the end of the template.
	#
	# Should be either used externally to act on basic templates,
	# or internally in the `rendering` method of specific templates.
	#
	# Mixing the internal and external uses should be avoided because
	# the final behavior will depend on the lazy invocation of `rendering`.
	#
	#     var t = new Template
	#     t.add("1")
	#     t.add("2")
	#     assert t.write_to_string == "12"
	fun add(element: Writable) do
		assert not is_frozen
		content.add element
	end

	# Append `element` and the end of the template then append a "\n".
	#
	#     var t = new Template
	#     t.addn("1")
	#     t.addn("2")
	#     assert t.write_to_string == "1\n2\n"
	fun addn(element: Writable) do
		add element
		add "\n"
	end

	# Append a bunch of elements at the end of the template.
	# See `add`.
	#
	#     var t = new Template
	#     t.add_all(["1", "2"])
	#     assert t.write_to_string == "12"
	fun add_all(elements: Collection[Writable]) do content.add_all elements

	# Append a bunch of elements at the end of the template with separations.
	# see `add`.
	#
	#     var t = new Template
	#     t.add_list(["1", "2", "3"], ", ", " and ")
	#     assert t.write_to_string == "1, 2 and 3"
	fun add_list(elements: Collection[Writable], sep, last_sep: Writable) do
		var last = elements.length - 2
		var i = 0
		for e in elements do
			content.add e
			if i < last then
				content.add sep
			else if i == last then
				content.add last_sep
			end
			i += 1
		end
	end

	# Is the template allowing more modification (`add`)
	var is_frozen = false

	# Disable further modification: no more `add` is allowed
	fun freeze
	do
		if is_frozen then return
		is_frozen = true
	end

	# Return a new basic template that is automatically added in `self` (using `add`)
	#
	# This is an easy way to provide a free insertion point in an existing template.
	#
	#     var t = new Template
	#     t.add("""void main(void) {""")
	#     var tdecl = t.new_sub # used to group declarations
	#     tdecl.add("int i; ")
	#     t.add("i = 1; ")
	#     tdecl.add("int j; ")
	#     t.add("j = i + 1; ")
	#     t.add("\}")
	#     assert t.write_to_string == """void main(void) {int i; int j; i = 1; j = i + 1; }"""
	fun new_sub: Template
	do
		var res = new Template
		add res
		return res
	end

	# Each sub-elements
	private var content = new Array[Writable]

	# Flag to avoid multiple rendering
	private var render_done = false

	# Call rendering, if not already done
	# Then freeze the template
	#
	# This method is only required in corner-cases since
	# `rendering` is automatically called when needed.
	fun force_render
	do
		if render_done then return
		render_done = true
		rendering
		freeze
	end

	# Do the full rendering and write the final content to a stream
	redef fun write_to(stream)
	do
		assert not is_writing
		is_writing = true
		force_render
		for e in content do
			e.write_to(stream)
		end
		is_writing = false
	end

	# Flag to avoid infinite recursivity if a template contains itself
	private var is_writing = false
end
lib/template/template.nit:21,1--216,3