Advanced - Examples

Recursive Macro Calls

Included content can use the 'include' or any other macro recursively when either the APT or XDoc format is used. (detected through the file extension or forced via source-content-type=(apt|xdoc))

Template with recursion "samples/recursive-macro-call.xdoc.vm":

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
<?xml version="1.0"?>
<document>
    <body>
        <table>
            <tr>
                <th style="vertical-align:middle; text-align:center; width:128px;">Recursive Call - Result:</th>
                <td>
                    <macro name="include">
                        <param name="message-box" value="$esc.xml($text)"/>
                    </macro>
                </td>
            </tr>
        </table>
    </body>
</document>

Used with:

%{include|source=samples/recursive-macro-call.xdoc.vm|text=Hello World - Recursive Macro Call}

Creates the following output:

Recursive Call - Result:
Hello World - Recursive Macro Call

Note: Existing macros that reference the document structure (like toc macro) will always refer to the document they are called in. Recursion may not make a lot sense with such macros.

Dynamic Snippets

Using velocity templates, snippets can be made dynamic so that certain content is always included whereas some snippets are static.

Source Content containing 2 Static Snippets and 2 Dynamic Snippets

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
<%-- START SNIPPET: ${id} --%>
<%@ page contentType="text/html;charset=UTF-8"%>
<html>
    <body>
<%-- END SNIPPET: ${id} --%>
  
        <!-- START SNIPPET: first -->
        <h2><% out.println("First Snippet"); %></h2>
        <!-- END SNIPPET: first -->
  
        <!-- START SNIPPET: second -->
        <h2><% out.println("Second Snippet"); %></h2>
        <!-- END SNIPPET: second -->
  
<%-- START SNIPPET: ${id} --%>
    </body>
</html>
<%-- END SNIPPET: ${id} --%>

Including Snippet 'first'

%{include|source=samples/dynamic-snippet.jsp|source-is-template=true|id=first}
2
3
4
8
16
17
<%@ page contentType="text/html;charset=UTF-8"%>
<html>
    <body>
        <h2><% out.println("First Snippet"); %></h2>
    </body>
</html>

Including Snippet 'second'

%{include|source=samples/dynamic-snippet.jsp|source-is-template=true|id=second}
2
3
4
12
16
17
<%@ page contentType="text/html;charset=UTF-8"%>
<html>
    <body>
        <h2><% out.println("Second Snippet"); %></h2>
    </body>
</html>

Attaching Content

Doxia :: Include Macro allows attaching content to generated pages that is then linked or embedded. Attaching content in this context means that any given content is stored to a local file, placed next to the page and a valid link is returned pointing to the local content to link or embed.

This functionality is currently used internally to attach CSS for highlighted snippets and also used by bundled extensions to provide extra functionality (e.g. tabbed panel). In all cases attaching content is performed either from extensions (source-class implementations with access to the SPI of DIM) or via Velocity templates calling one of the "attach*" methods that can be found in $globals.

Note: All attached content is stored as GZIP and plain version to reduce transfer sizes on webservers that support the ".gz" extension. Images or non-compressible content may or may not get a GZIP version depending on the compression ratio that can be achieved.

Attaching Contents using Links

The easiest way to attach content and link to it is using the bundled link template.

%{include|source=classpath:/templates/dim/link.xdoc.vm|href=URL/to/file.xy|label=Click here to see XY}
%{include|source=classpath:/templates/dim/link.xdoc.vm|href=classpath:/templates/dim/link.xdoc.vm|filename=link.xdoc.vm|label=Click here...
Click here to view the bundled "link" template

Attaching Scripts, CSS and Binary using $globals

Scripts or CSS can be attached and embedded within a velocity template using conditional statement like shown in the example below. The statements are conditional as CSS and Scripts can be attached only if the document output (sink) supports these content types, thus attaching them can fail without having an actual exception.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
<?xml version="1.0"?>
<document>
    <body>
        <!-- Attaching JavaScript -->
        #if ($globals.attachJs("js/my-bundled-library.js", "classpath:/js-bundle/my-bundled-library.js"))
            <script language="javascript">
                doSomethingInLibrary();
            </script>
        #end
  
        <!-- Attaching StyleSheets -->
        #if ($globals.attachCss("css/my-style.css", "classpath:/css-bundle/my-style.css"))
            <h1 class="my-headline">Styled Headline</h1>
        #end
  
        <!-- Attaching images -->
        #set ($href = $globals.attachBinaryContent("images/my-image.png", "classpath:/image-bundle/my-image.png"))
        <img src="$href"/>
    </body>
</document>

Note: The "content" in the example above is selected using a "classpath:" URI. The methods attachCss and attachJs support also inline content definition, which means any content that does not start with "classpath:" is considered the actual style sheet or script. (Fetching content from a file or URL can be achieved with "$globals.fetchText("some/file.txt")")
Once a CSS or JS is attached it, can be used right away as any relevant <style> and <script> tags are generated when a call to the attach* method returns true.

The "*Binary" methods above always expect a link pointing to the content to transfer and attach while the return value is a valid link to the attached content that can be used in src and href attributes inside the generate site.