diff src/nabble/view/naml/macro_viewer.naml @ 0:7ecd1a4ef557

add content
author Franklin Schmidt <fschmidt@gmail.com>
date Thu, 21 Mar 2019 19:15:52 -0600
parents
children 62faaba01dd2
line wrap: on
line diff
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/nabble/view/naml/macro_viewer.naml	Thu Mar 21 19:15:52 2019 -0600
@@ -0,0 +1,1316 @@
+<namespace name="naml_tools"/>
+
+<macro name="current_macro_source" dot_parameter="do" requires="naml_tools">
+	<n.if.command_exists id="[n.current_command_id/]">
+		<then>
+			<n.macro_source.
+				id="[n.current_command_id/]"
+				base="[n.current_base_classes/]"
+				breadcrumbs="[n.current_breadcrumbs/]"
+			>
+				<n.do/>
+			</n.macro_source.>
+		</then>
+		<else>
+			<n.invalid_command_html/>
+		</else>
+	</n.if.command_exists>
+</macro>
+
+<macro name="macro_viewer_header" dot_parameter="text">
+	<n.put_in_head.>
+		<script type="text/javascript">
+			function openVideo() {
+				$('#demo-video').slideDown();
+			};
+			function closeVideo() {
+				$('#demo-video').slideUp();
+			};
+		</script>
+	</n.put_in_head.>
+
+	<div style="clear:both;padding-top:1em">
+		<div style="float:left;margin-top:1.1em">
+			<n.macro_options_dropdown/>
+		</div>
+		<h1 style="margin:.5em 0 1em"><n.text/></h1>
+	</div>
+
+	<div class="second-font" style="font-size:80%;float:right;margin-top:-4.3em;padding:.3em 0">
+		<a href="http://naml.nabble.com/" target="_top">NAML documentation</a>
+		&nbsp;
+		<n.naml_video_link/>
+	</div>
+</macro>
+
+<macro name="naml_video_link">
+	<a href="#" onclick="openVideo()">Watch a video</a>
+	<div id="demo-video" style="display:none;text-align:center;position:fixed;z-index:1001;width:100%;top:3em">
+		<div class="shaded-bg-color rounded drop-shadow" style="width:450px;height:400px;margin:0 auto;text-align:center">
+			<div style="text-align:right;padding:.3em .9em">
+				<a href="#" onclick="closeVideo()"><t>Close</t></a>
+			</div>
+			<iframe width="425" height="349" src="http://www.youtube.com/embed/06hd0keRN80" frameborder="0" allowfullscreen="true"></iframe>
+		</div>
+	</div>
+</macro>
+
+<macro name="macro_viewer" requires="servlet">
+	<n.naml_tools.>
+        <n.current_macro_source.>
+            <n.html>
+                <head>
+                    <meta name="robots" content="noindex,nofollow"/>
+                    <n.title.><n.name/></n.title.>
+                    <n.macro_viewer_stylesheet/>
+                    <n.redirect_if_overridden/>
+                    <n.codemirror_shared_head/>
+                    <n.macro_viewer_js/>
+                </head>
+                <body>
+                    <n.macro_viewer_header.>
+                        <n.name/>
+                    </n.macro_viewer_header.>
+
+                    <n.important_notices/>
+                    <n.source_panel/>
+                </body>
+            </n.html>
+        </n.current_macro_source.>
+	</n.naml_tools.>
+</macro>
+
+<macro name="title" dot_parameter="text" requires="macro_source">
+  <title><n.root_node.subject/> | NAML - <n.text/></title>
+</macro>
+
+<macro name="breadcrumbs_content" requires="macro_source, naml_tools">
+	<n.root_node.node_breadcrumbs />
+	| NAML<sup class="important">alpha</sup>
+	| <n.naml_breadcrumbs/>
+</macro>
+
+<macro name="breadcrumbs_content" requires="naml_tools">
+	<n.root_node.node_breadcrumbs />
+	| NAML<sup class="important">alpha</sup>
+</macro>
+
+<macro name="naml_breadcrumbs">
+	<n.navigation_breadcrumbs.loop.parts.>
+		<n.if.has_more_elements>
+			<then>
+				<a href="[n.part_path/]"><n.name/></a>
+				<span class="weak-color breadcrumbs-arrow" style="padding:0 .25em">
+					&rsaquo;
+				</span>
+			</then>
+			<else.name/>
+		</n.if.has_more_elements>
+	</n.navigation_breadcrumbs.loop.parts.>
+</macro>
+
+<macro name="codemirror_shared_head">
+	<style type="text/css">
+		.CodeMirror-line-numbers {
+			font-family: verdana, arial, sans-serif;
+			font-size: 11pt;
+			width: 2.2em;
+			text-align: right;
+			padding-right: .3em;
+			line-height: normal;
+			border-right-width:2px;
+			border-right-style:solid;
+		}
+		#resizebar {
+			height:8px;
+			background:url('/images/grip.png') #d8d8d8 repeat;
+			border:1px solid #aaa;
+			cursor:n-resize;
+		}
+	</style>
+	<script src="/util/codemirror/js/codemirror.js"></script>
+	<script src="/util/codemirror/js/highlight.js"></script>
+	<script src="/util/codemirror/js/stringstream.js"></script>
+	<script src="/util/codemirror/js/tokenize.js"></script>
+	<script src="/util/codemirror/js/parsexml.js"></script>
+	<script type="text/javascript">
+		<![CDATA[
+		function newEditor(height) {
+			var e = CodeMirror.fromTextArea('txt_basic', {
+				parserfile: "parsexml.js",
+				stylesheet: "/util/codemirror/css/xmlcolors.css",
+				path: "/util/codemirror/js/",
+				lineNumbers: true,
+				height: height,
+				indentUnit: 4,
+			});
+			var $wrapping = $('#txt_basic').next();
+			$wrapping.attr('id', 'wrapping_basic');
+			$wrapping.css('margin-top', '.4em');
+			$wrapping.addClass('medium-border-color border1');
+			addResizeBar($wrapping);
+			$('div.CodeMirror-line-numbers', $wrapping).addClass('shaded-bg-color medium-border-color');
+			return e;
+		};
+
+		function addResizeBar($wrapping) {
+			$wrapping.after('<div id="resizebar"></div>');
+
+			var dragging = false;
+			function startDrag(e) {
+				if ($(e.target).attr('id') == 'resizebar')
+					dragging = true;
+				if (dragging && typeof e.preventDefault != 'undefined')
+					e.preventDefault();
+			};
+			function endDrag(e) {
+				dragging = false;
+			};
+			function drag(e, x, y) {
+				e.stopPropagation();
+				if (dragging) {
+					var h = y - $wrapping.offset().top - 5;
+					$wrapping.height(h < 100? 100 : h);
+				}
+			};
+			function onSelectStart() {
+				if (dragging) return false;
+			};
+
+			function isCorrectFrame(f) {
+				try {
+					frame.document.location.href;
+					return true;
+				} catch(err) {
+					return false;
+				}
+			}
+			var index = 0;
+			var frame = window.frames[index++];
+			while (!isCorrectFrame(frame)) {
+				frame = window.frames[index++];
+			}
+			$(frame.document)
+				.mousemove(function(e) {
+					var x = e.pageX + $wrapping.offset().left;
+					var y = e.pageY + $wrapping.offset().top;
+					drag(e, x, y);
+				})
+				.mouseup(function(e) { endDrag(e); })
+				.select(onSelectStart);
+
+			$(document)
+				.mousemove(function(e) { drag(e, e.pageX, e.pageY); })
+				.mousedown(function(e) { startDrag(e); })
+				.mouseup(function(e) { endDrag(e); })
+				.select(onSelectStart);
+		};
+		var basicEditor;
+		function inlineEditor(height, line, col) {
+			if (!basicEditor)
+				basicEditor = newEditor(height);
+			function showCaret() {
+				var $lines = $('#wrapping_basic div.CodeMirror-line-numbers').children();
+				if (basicEditor.editor && $lines.size() > 5) {
+					if (line) {
+						if (col) {
+							var ln = basicEditor.nthLine(line);
+							basicEditor.selectLines(ln, col);
+						} else
+							basicEditor.jumpToLine(line);
+					} else
+						basicEditor.jumpToLine(1);
+				} else
+					setTimeout(showCaret, 200);
+			};
+			showCaret();
+		};
+		function getLineNumber(s, token) {
+			var line = 1;
+			var pos = s.indexOf(token);
+			for (var i=0; i < pos; i++) {
+				if (s.charAt(i) == '\n')
+					line++;
+			}
+			return line;
+		};
+		function formatError(msg) {
+			var h = msg.replace(/</g, "&lt;");
+			h = h.replace(/>/g, "&gt;");
+			h = h.replace(/\n/g, "<br/>");
+			h = h.replace(/(\t)|([ ]{6})/g, "<span style='padding:0 2em'>&nbsp;</span>");
+			h = '<img src="/images/icon_alert_sm.png" class="image16"/> ' + h;
+			return h;
+		};
+		]]>
+	</script>
+</macro>
+
+<macro name="macro_viewer_js">
+	<script type="text/javascript">
+		var isCustomTweak = <n.is_custom_tweak/>;
+		var pBase = '&base=<n.hide_null.current_base_classes/>';
+		var pBreadcrumbs = '<n.hide_null.current_breadcrumbs/>';
+		pBreadcrumbs = pBreadcrumbs == ''? '' : '&breadcrumbs=' + pBreadcrumbs;
+		var isSiteAdmin = <n.visitor.is_site_admin/>;
+
+		var tweakFileContents = "<n.javascript_string_encode.hide_null.tweak_file_contents/>";
+        var macroOpeningTag = "<n.javascript_string_encode.hide_null.macro_opening_tag/>";
+		$(document).ready(function() {
+			function lineSelector(e) {
+				return 'div.line'+e.id.substring(8);
+			};
+			var $lineDivs = $('table.code div.line-contents');
+			$lineDivs.hover(
+				function() { $(lineSelector(this), $(this).parent().prev()).css('font-weight','bold').addClass('dark-bg-color'); },
+				function() { $(lineSelector(this), $(this).parent().prev()).css('font-weight','normal').removeClass('dark-bg-color'); }
+			);
+			function fixHeights() {
+				$lineDivs.each(function() {
+					var h = $(this).outerHeight();
+					var $table = $(this).parents('table');
+					$(lineSelector(this), $table).height(h);
+				});
+			}
+			$(window).resize(fixHeights);
+			fixHeights();
+
+			var $textarea = $('#txt_basic');
+			var textareaValue = $textarea.val().replace(/\s*/g, '');
+			var originalFileContents = tweakFileContents.replace(/\s*/g, '');
+			if (textareaValue != originalFileContents) {
+				showEditor();
+			}
+			window.onbeforeunload = function() {
+				$textarea.val(basicEditor.getCode());
+			};
+		});
+
+		function openNamlLogin() {
+			$('#naml-login').slideDown();
+		};
+
+		function showEditor() {
+			if (!isSiteAdmin) {
+				openNamlLogin();
+				return;
+			}
+			$('#saveButton,#cancelButton,#wrapping_basic,#resizebar').show();
+			$('#editButton,#removeButton').hide();
+			if (isCustomTweak)
+				$('#current-source').hide();
+			else
+				$('#overrides-arrow').show();
+			var line = getLineNumber(tweakFileContents, macroOpeningTag);
+			inlineEditor('20em', line);
+		};
+		function saveChanges() {
+			notice('Saving... Please wait');
+			var call = '/template/NamlServlet.jtp?macro=save_tweak&id=<n.id/>' + pBase + pBreadcrumbs;
+			var code = basicEditor.getCode();
+			if (code.match(/^\s*$/) != null) {
+				notice('Error Found', 3000, 1500);
+				var msg = "Error: invalid macro code.";
+				$('#error-box').html(msg).show();
+				return;
+			}
+			var params = { contents: code };
+			$.post(call, params,
+				function(data) {
+					var result = eval('(' + data + ')');
+					if (result.error != null) {
+						notice('Error Found', 3000, 1500);
+						var $errorBox = $('#error-box');
+						$errorBox.html(formatError(result.error)).show();
+						if ($errorBox.height() > 150) {
+							$errorBox.css('overflow-y','scroll').height(150);
+						}
+					} else {
+						pBase = result.base == null? pBase : '&base=' + result.base;
+						pBreadcrumbs = result.breadcrumbs == null? pBreadcrumbs : '&breadcrumbs=' + result.breadcrumbs;
+						var url = '/template/NamlServlet.jtp?macro=macro_viewer&id=' + result.macroId + pBase + pBreadcrumbs;
+						window.location = url;
+					}
+				}
+			);
+		};
+		function cancelChanges() {
+			$('#saveButton,#cancelButton,#wrapping_basic,#resizebar,#error-box').hide();
+			$('#editButton,#removeButton').show();
+			if (isCustomTweak)
+				$('#current-source').show();
+			else
+				$('#overrides-arrow').hide();
+			basicEditor.setCode(tweakFileContents);
+		};
+		function removeOverride() {
+			if (!isSiteAdmin) {
+				openNamlLogin();
+				return;
+			}
+			<n.if.is_override>
+				<then>
+					var confirmQuestion = "Do you really want to remove this override?";
+					var nextUrl = "<n.use_text_encoder.path_to_overridden_macro/>";
+				</then>
+				<else>
+					var confirmQuestion = "Do you really want to remove this macro?";
+					var nextUrl = "<n.use_text_encoder.macro_deleted_path/>";
+				</else>
+			</n.if.is_override>
+			if( !confirm(confirmQuestion) )
+				return;
+			var call = '/template/NamlServlet.jtp?macro=revert_tweak&id=<n.id/>' + pBase + pBreadcrumbs;
+			$.get(call, function(data) {
+				if (Nabble.trim(data) == 'ok')
+					window.location = nextUrl;
+			});
+		};
+	</script>
+</macro>
+
+<macro name="macro_viewer_stylesheet">
+	<style type="text/css">
+		table.code {
+			width: 100%;
+			font-family: verdana, arial, sans-serif;
+			font-size: 11pt;
+			border-collapse:collapse;
+			margin:.35em 0;
+		}
+		table.code tr {
+			vertical-align:top;
+		}
+		table.code td {
+			padding: 0;
+		}
+		table.code td.line-number {
+			width: 2em;
+			text-align:right;
+			padding-right:.3em;
+			border-right-width:2px;
+			border-right-style:solid;
+		}
+		table.code td.line-contents {
+			padding-left: .5em;
+		}
+		table.code a {
+			text-decoration:none;
+		}
+		table.code a:hover {
+			text-decoration:underline;
+		}
+	</style>
+</macro>
+
+<macro name="source_panel" requires="macro_source">
+	<n.editor_left_controls/>
+
+	<n.documentation/>
+	<div style="clear:both">
+		<n.source_contents/>
+		<n.overridden_macro_source/>
+	</div>
+</macro>
+
+<macro name="source_contents">
+	<n.if.not.is_binary>
+		<then>
+			<div id="error-box" class="error-message" style="padding:.5em;display:none"></div>
+			<textarea id="txt_basic" style="display:none"><n.encode.tweak_file_contents/></textarea>
+			<div id="current-source">
+				<div id="overrides-arrow" style="display:none">
+					<n.overrides_arrow/>
+				</div>
+				<n.show_notice_if_not_compiled/>
+				<table class="code">
+					<n.source_row/>
+					<tr>
+						<n.line_numbers_column/>
+						<n.line_contents_column/>
+					</tr>
+				</table>
+			</div>
+		</then>
+	</n.if.not.is_binary>
+</macro>
+
+<macro name="show_notice_if_not_compiled">
+	<n.if.not.is_compiled>
+		<then>
+			<div class="info-message rounded" style="padding:.4em; margin:.2em 0">
+				The source code below doesn't have navigation links because no usage has been compiled yet.
+				Navigation links depend on how and where the macro is used, so first you may
+				<a id="find-usages" href="#">try finding all usages of "<n.name/>"</a>.
+				<n.current_find_usages_path element_name="find-usages"/>
+			</div>
+		</then>
+	</n.if.not.is_compiled>
+</macro>
+
+<macro name="line_numbers_column">
+	<td class="line-number weak-color medium-border-color shaded-bg-color">
+		<n.rows.loop.>
+			<div class="line[n.file_line_number/]"><n.file_line_number/></div>
+		</n.rows.loop.>
+	</td>
+</macro>
+
+<macro name="line_contents_column">
+	<td class="line-contents">
+		<n.rows.loop.>
+			<div id="contents[n.file_line_number/]" class="line-contents">
+				<n.current_row_contents/>
+			</div>
+		</n.rows.loop.>
+	</td>
+</macro>
+
+<macro name="current_row_contents" requires="macro_row_list">
+	<n.current_row.>
+		<n.if.is_blank>
+			<then>&nbsp;</then>
+			<else>
+				<n.loop.parts.>
+					<n.if.not.is_null.id>
+						<then>
+							<n.remove_spaces_between_tags.>
+								<a href="[n.part_path/]"><n.tag/></a>
+								<n.part_tooltip/>
+							</n.remove_spaces_between_tags.>
+						</then>
+						<else.name/>
+					</n.if.not.is_null.id>
+				</n.loop.parts.>
+			</else>
+		</n.if.is_blank>
+	</n.current_row.>
+</macro>
+
+<macro name="part_tooltip" requires="command_info">
+	<n.tooltip.>
+		<n.if.is_binary>
+			<then>
+				<div class="bold">Binary</div>
+				<n.tooltip_small_row.><b>Namespace:</b> <n.namespace_class/></n.tooltip_small_row.>
+				<n.tooltip_parameters/>
+			</then>
+			<else>
+				<div class="bold">Macro</div>
+				<n.if.not.is_empty.required_namespaces>
+					<then>
+						<n.tooltip_small_row.><b>Requires:</b> <n.required_namespaces/></n.tooltip_small_row.>
+					</then>
+				</n.if.not.is_empty.required_namespaces>
+				<n.tooltip_parameters/>
+			</else>
+		</n.if.is_binary>
+	</n.tooltip.>
+</macro>
+
+<macro name="tooltip_parameters">
+	<n.if.has_parameters>
+		<then>
+			<n.tooltip_small_row.>
+				<b>Parameters:</b>
+				<n.remove_spaces.parameter_names.loop.>
+					<n.current_string/>
+					<n.if.has_more_strings>
+						<then>,&ensp;</then>
+					</n.if.has_more_strings>
+				</n.remove_spaces.parameter_names.loop.>
+			</n.tooltip_small_row.>
+		</then>
+	</n.if.has_parameters>
+</macro>
+
+<macro name="important_notices">
+	<n.if.has_tweak_exception>
+		<then>
+			<div class="weak-color info-message rounded" style="margin:.3em 0;padding:.3em .2em">
+				<table style="width:100%;table-layout:fixed">
+					<tr style="vertical-align:top">
+						<td style="width:32px"><img src="/images/icon_alert.png" style="width:32px;height:32px"/></td>
+						<td>
+							<b>Error Found</b><br/>
+							An error was found in the NAML code of this application &ndash;
+							<span class="view-exception-details">
+								<a href="#" onclick="showExceptionDetails(true)">View Details</a>
+							</span>
+							<span class="hide-exception-details invisible">
+								<a href="#" onclick="showExceptionDetails(false)">Hide Details</a>
+							</span>
+							| <n.advanced_editor_link text="[t]Go to NAML Editor[/t]"/>
+
+							<n.put_in_head.>
+								<style type="text/css">
+									div.stacktrace {
+										width:100%;
+										overflow:auto;
+										white-space:nowrap;
+										display:none;
+										margin-top:.5em;
+										font-size:80%;
+									}
+								</style>
+								<script type="text/javascript">
+									function showExceptionDetails(show) {
+										if (show) {
+											$('div.stacktrace').slideDown(function() { $(this).show() });
+											$('span.view-exception-details').hide();
+											$('span.hide-exception-details').show();
+										} else {
+											$('div.stacktrace').hide();
+											$('span.view-exception-details').show();
+											$('span.hide-exception-details').hide();
+										}
+									};
+								</script>
+							</n.put_in_head.>
+							<div class="stacktrace">
+								<n.regex_replace_all. pattern="\t+" replacement="&nbsp;&nbsp;">
+									<n.regex_replace_all. pattern="\n+" replacement="[br/]">
+										<n.use_html_encoder.encode.tweak_exception_message/>
+									</n.regex_replace_all.>
+								</n.regex_replace_all.>
+							</div>
+						</td>
+					</tr>
+				</table>
+			</div>
+		</then>
+	</n.if.has_tweak_exception>
+</macro>
+
+<macro name="path_to_overridden_macro">
+	<n.macro_viewer_path id="[n.macro_overridden_id/]" base="[n.current_base_classes/]" breadcrumbs="[n.current_breadcrumbs/]"/>
+</macro>
+
+<macro name="path_to_macro_which_overrides">
+	<n.macro_viewer_path id="[n.macro_which_overrides_id/]" base="[n.current_base_classes/]" breadcrumbs="[n.current_breadcrumbs/]"/>
+</macro>
+
+<macro name="save_button" requires="macro_source">
+	<button id="saveButton" class="toolbar" style="font-weight:bold;display:none" onclick="saveChanges()">
+		Save Changes
+	</button>
+</macro>
+
+<macro name="cancel_button" requires="macro_source">
+	<button id="cancelButton" class="toolbar" style="font-weight:bold;display:none" onclick="cancelChanges()">
+		Cancel
+	</button>
+</macro>
+
+<macro name="edit_button" requires="macro_source">
+	<button id="editButton" class="toolbar" style="font-weight:bold" onclick="showEditor()">
+		<img src="/images/tool.png" style="width:16px;height:17px;vertical-align:-25%"/>
+		<n.if.is_custom_tweak>
+			<then>
+				<n.if.is_override>
+					<then>Edit this override</then>
+					<else>Edit this macro</else>
+				</n.if.is_override>
+			</then>
+			<else>Override this macro</else>
+		</n.if.is_custom_tweak>
+	</button>
+</macro>
+
+<macro name="remove_button" requires="macro_source">
+	<n.if.is_custom_tweak>
+		<then>
+			<button id="removeButton" class="toolbar" style="font-weight:bold" onclick="removeOverride()">
+				<img src="/images/remove_sm.png" style="width:15px;height:15px;vertical-align:-25%"/>
+				<n.if.is_override>
+					<then>Remove override</then>
+					<else>Remove macro</else>
+				</n.if.is_override>
+			</button>
+		</then>
+	</n.if.is_custom_tweak>
+</macro>
+
+<macro name="editor_left_controls">
+	<div style="margin:.5em 0">
+		<n.if.not.is_binary>
+			<then>
+				<n.save_button/>
+				<n.cancel_button/>
+				<n.edit_button/>
+				<n.remove_button/>
+				&nbsp;&nbsp;
+				<n.usages_link/>
+			</then>
+		</n.if.not.is_binary>
+	</div>
+
+	<n.if.not.visitor.is_site_admin>
+		<then>
+			<div id="naml-login" class="border1 medium-border-color" style="padding:1em; display:none">
+				<div class="bold">You must login as an administrator of <n.root_node.subject/>.</div>
+				<div class="weak-color" style="margin-bottom:1em">
+					If you are not the administrator,
+					you can <n.nabble_homepage_link.>create your own Nabble app</n.nabble_homepage_link.> and customize its NAML code!
+				</div>
+
+				<n.nextUrl_field.set_value value="[n.use_text_encoder.current_url/]"/>
+				<n.login_form/>
+			</div>
+		</then>
+	</n.if.not.visitor.is_site_admin>
+</macro>
+
+<macro name="usages_link" requires="macro_source">
+	<a id="usages-link" href="#">Usages of this macro</a>
+	<n.current_find_usages_path element_name="usages-link"/>
+</macro>
+
+<macro name="macro_options_dropdown">
+	<n.dropdown.
+		id="macrodropdown"
+		element="[n.options_button/]"
+		loadOnClick="/template/NamlServlet.jtp?macro=macro_dropdown_later"
+	>
+		<n.menu_custom_macros/>
+		<n.menu_configuration_macros/>
+		<n.menu_new_macro/>
+		<n.menu_macro_search/>
+		<n.menu_view_logs/>
+		<n.menu_separator/>
+		<n.menu_open_advanced_editor/>
+	</n.dropdown.>
+
+	<n.custom_macros_contents/>
+	<n.configuration_macros_contents/>
+</macro>
+
+<macro name="options_button">
+	<button class="toolbar" style="font-weight:bold" title="[t]Click for more options[/t]">
+		<img src="/images/gear.png" class="image16"/>
+		<img src="/images/more.png" width="10" height="10"/>
+	</button>
+</macro>
+
+<macro name="macro_dropdown_later" requires="servlet">
+	<n.javascript_response/>
+	<n.menu_new_macro/>
+	<n.menu_open_advanced_editor/>
+</macro>
+
+<macro name="menu_custom_macros">
+	dropdown.addCustomSubmenu('Customized macros', 'custom-macros-box');
+</macro>
+
+<macro name="menu_configuration_macros">
+	<n.if.has_configuration_macros>
+		<then>dropdown.addCustomSubmenu('Macros overridden by configurations', 'configuration-macros-box');</then>
+	</n.if.has_configuration_macros>
+</macro>
+
+<macro name="custom_macros_contents">
+	<n.custom_macros.list_macros_available id="custom-macros-box"/>
+</macro>
+
+<macro name="configuration_macros_contents">
+	<n.if.has_configuration_macros>
+		<then.configuration_macros.list_macros_available id="configuration-macros-box"/>
+	</n.if.has_configuration_macros>
+</macro>
+
+<macro name="list_macros_available" parameters="id" requires="command_list">
+	<n.put_in_head.>
+		<style type="text/css">
+			ul.dropdown-submenu {
+				max-height:20em;
+				overflow-y:auto;
+			}
+			ul.dropdown-submenu li {
+				padding-right:1em;
+			}
+		</style>
+	</n.put_in_head.>
+	<ul id="[n.id/]" class="dropdown-submenu light-bg-color medium-border-color drop-shadow">
+		<n.if.has_more_elements>
+			<then>
+				<n.loop.current_command.>
+					<li class="nowrap">
+						<a href="[n.command_path/]"><n.name/></a>
+						<n.if.not.is_empty.required_namespaces>
+							<then>
+								<n.tooltip. delay="50" position="right">Requires <n.required_namespaces/></n.tooltip.>
+							</then>
+						</n.if.not.is_empty.required_namespaces>
+					</li>
+				</n.loop.current_command.>
+			</then>
+			<else>
+				<li class="weak-color" style="padding:.4em .8em">None</li>
+			</else>
+		</n.if.has_more_elements>
+	</ul>
+</macro>
+
+<macro name="menu_macro_search">
+	dropdown.add('searchMacros', '<n.javascript_string_encode.macro_search_link/>');
+</macro>
+
+<macro name="macro_search_link">
+	<a href="[n.macro_search_path/]">Search macros</a>
+</macro>
+
+<macro name="macro_search_path">
+	<n.encode_url.>
+		/template/NamlServlet.jtp?macro=macro_search_page
+	</n.encode_url.>
+</macro>
+
+<macro name="menu_view_logs">
+	dropdown.add('viewLogs', '<n.javascript_string_encode.root_node.view_logs_link/>');
+</macro>
+
+<macro name="menu_new_macro">
+	<n.if.is_in_command name="dropdown">
+		<then>
+			dropdown.add('newMacro', '<n.javascript_string_encode.new_macro_link/>', 'display:none');
+		</then>
+		<else>
+			<n.if.visitor.is_site_admin>
+				<then>
+					NabbleDropdown.show('newMacro');
+				</then>
+			</n.if.visitor.is_site_admin>
+		</else>
+	</n.if.is_in_command>
+</macro>
+
+<macro name="menu_open_advanced_editor">
+	<n.if.is_in_command name="dropdown">
+		<then>
+			dropdown.add('openAdvEditor', '<n.javascript_string_encode.advanced_editor_link/>', 'display:none');
+		</then>
+		<else>
+			<n.if.visitor.is_site_admin>
+				<then>
+					NabbleDropdown.show('openAdvEditor');
+				</then>
+			</n.if.visitor.is_site_admin>
+		</else>
+	</n.if.is_in_command>
+</macro>
+
+<macro name="advanced_editor_link" dot_parameter="text" parameters="title, class">
+	<a href="[n.current_advanced_editor_path/]" class="[n.class/]" rel="nofollow" title="[n.title/]" target="_top">
+		<n.default. to="[t]Go to Advanced Editor[/t]"><n.text/></n.default.>
+	</a>
+</macro>
+
+<macro name="current_advanced_editor_path">
+	<n.advanced_editor_path prev_url="[n.current_url/]"/>
+</macro>
+
+<macro name="new_macro_link">
+	<a href="[n.new_macro_path/]">New macro</a>
+</macro>
+
+<macro name="macro_viewer_path" parameters="id,base,breadcrumbs">
+	<n.encode_url.remove_spaces.>
+		/template/NamlServlet.jtp?macro=macro_viewer
+		&id=<n.encode_text.id/>
+		<n.add_to_path name="base" value="[n.base/]" />
+		<n.add_to_path name="breadcrumbs" value="[n.breadcrumbs/]" />
+	</n.encode_url.remove_spaces.>
+</macro>
+
+<macro name="part_path" requires="command_info">
+	<n.macro_viewer_path>
+		<id><n.id/></id>
+		<base><n.base/></base>
+		<breadcrumbs><n.naml_breadcrumbs/></breadcrumbs>
+	</n.macro_viewer_path>
+</macro>
+
+<macro name="macro_viewer_page_link">
+	<a href="[n.macro_viewer_page_path/]" rel="nofollow">Edit this page</a>
+</macro>
+
+<macro name="macro_viewer_page_path">
+	<n.macro_viewer_path>
+		<id><n.page_template_command_id/></id>
+		<base><n.page_base_classes/></base>
+	</n.macro_viewer_path>
+</macro>
+
+<macro name="find_usages_path" parameters="id,base,breadcrumbs">
+	<n.encode_url.remove_spaces.>
+		/template/NamlServlet.jtp?macro=find_usages_page
+		&id=<n.encode_text.id/>
+		<n.add_to_path name="base" value="[n.base/]" />
+		<n.add_to_path name="breadcrumbs" value="[n.breadcrumbs/]" />
+	</n.encode_url.remove_spaces.>
+</macro>
+
+<macro name="current_find_usages_path" parameters="element_name">
+	<script type="text/javascript">
+		<n.compress.>
+			var _path = '/template/NamlServlet.jtp?';
+			var _p1 = 'macro=find_usages_page';
+			var _p2 = '&id=<n.current_command_id/>';
+
+			<n.if.not.is_null.current_base_classes>
+				<then>var _p3 = '&base=<n.current_base_classes/>';</then>
+				<else> var _p3 = '';</else>
+			</n.if.not.is_null.current_base_classes>
+
+			<n.if.not.is_null.current_breadcrumbs>
+				<then>var _p4 = '&breadcrumbs=<n.current_breadcrumbs/>';</then>
+				<else> var _p4 = '';</else>
+			</n.if.not.is_null.current_breadcrumbs>
+
+			var _link = document.getElementById('<n.element_name/>');
+			$(document).ready(function() {
+				$(_link).click(function() {
+					notice('Finding Usages... Please wait');
+					window.location = _path+_p1+_p2+_p3+_p4+'&js='+Math.random();
+				});
+			});
+		</n.compress.>
+	</script>
+</macro>
+
+<macro name="find_usages_page" requires="servlet">
+	<n.if.not.is_null.get_parameter name="js">
+		<then>
+			<n.if.command_exists id="[n.current_command_id/]">
+				<then>
+					<n.macro_source.
+						id="[n.current_command_id/]"
+						base="[n.current_base_classes/]"
+						breadcrumbs="[n.current_breadcrumbs/]"
+					>
+						<n.find_usages_html/>
+					</n.macro_source.>
+				</then>
+				<else>
+					<n.invalid_command_html/>
+				</else>
+			</n.if.command_exists>
+		</then>
+	</n.if.not.is_null.get_parameter>
+</macro>
+
+<macro name="find_usages_html" requires="macro_source">
+	<n.compile_if_needed/>
+	<n.naml_tools.>
+		<n.html>
+			<head>
+				<meta name="robots" content="noindex,nofollow"/>
+				<n.title.>Usages of <n.name/></n.title.>
+				<style type="text/css">
+					div.usage-path { padding: .5em; }
+				</style>
+			</head>
+			<body>
+				<n.macro_viewer_header.>
+					Usages of <n.name/>
+				</n.macro_viewer_header.>
+
+				<n.macro_usages.>
+					<n.if.not.has_more_elements>
+						<then>
+							<p><b>No usages found.</b> Some possible reasons are:</p>
+							<ul>
+								<li>This macro is called directly from the URL or from the java code;</li>
+								<li>This macro is not used at all;</li>
+							</ul>
+							<p>&laquo; <a href="javascript:void history.back()">Go Back</a></p>
+						</then>
+					</n.if.not.has_more_elements>
+
+					<n.loop.>
+						<div class="[n.alternate var='usages' first_value='usage-path' second_value='usage-path light-bg-color'/]">
+							<n.remove_spaces_between_tags.>
+								<n.current_usage.loop.>
+									<a href="[n.current_command.command_path/]"><n.current_command.name/></a>
+									<n.if.has_more_elements>
+										<then><span style="padding:0 .5em">&rsaquo;</span></then>
+									</n.if.has_more_elements>
+								</n.current_usage.loop.>
+							</n.remove_spaces_between_tags.>
+						</div>
+					</n.loop.>
+				</n.macro_usages.>
+			</body>
+		</n.html>
+	</n.naml_tools.>
+</macro>
+
+<macro name="redirect_if_overridden" requires="macro_source">
+	<n.if.has_macro_which_overrides>
+		<then>
+			<script type="text/javascript">
+				location = '<n.use_text_encoder.path_to_macro_which_overrides/>';
+			</script>
+		</then>
+	</n.if.has_macro_which_overrides>
+</macro>
+
+<subroutine name="overridden_macro_source" requires="basic,nabble,servlet,html,macro_source">
+	<n.if.has_macro_overridden>
+		<then>
+			<n.macro_source. id="[n.macro_overridden_id/]" base="[n.current_base_classes/]" breadcrumbs="[n.current_breadcrumbs/]">
+				<n.overrides_arrow/>
+				<table class="code">
+					<n.source_row/>
+					<tr>
+						<n.line_numbers_column/>
+						<n.line_contents_column/>
+					</tr>
+				</table>
+				<n.overridden_macro_source/>
+			</n.macro_source.>
+		</then>
+	</n.if.has_macro_overridden>
+</subroutine>
+
+<macro name="overrides_arrow" requires="macro_source">
+	<div style="font-weight:bold;margin:.5em">
+		<span style="font-size:300%;font-family:Arial,Sans-serif;line-height:.9em;vertical-align:-15%">&darr;</span>
+		<n.if.is_custom_tweak>
+			<then>Overrides administrator change</then>
+			<else>
+				<n.if.is_configuration_tweak>
+					<then>Overrides configuration</then>
+					<else>Overrides default macro</else>
+				</n.if.is_configuration_tweak>
+			</else>
+		</n.if.is_custom_tweak>
+	</div>
+</macro>
+
+<macro name="source_row" requires="macro_source">
+	<tr>
+		<td class="line-number weak-color medium-border-color shaded-bg-color" style="font-size:75%;padding-bottom:.4em">...</td>
+		<td class="line-contents weak-color" style="font-size:75%;padding-bottom:.4em">
+			in <a href="[n.source_path/]"><n.clean_source_name.source/></a>
+		</td>
+	</tr>
+</macro>
+
+<macro name="clean_source_name" dot_parameter="source">
+	<n.regex_replace_all. pattern="^.+:" replacement="">
+		<n.source/>
+	</n.regex_replace_all.>
+</macro>
+
+<macro name="revert_tweak" requires="servlet">
+	<n.if.visitor.is_site_admin>
+		<then.macro_editor. id="[n.current_command_id/]" base="[n.current_base_classes/]" breadcrumbs="[n.current_breadcrumbs/]">
+			<n.revert/>
+			ok
+		</then.macro_editor.>
+	</n.if.visitor.is_site_admin>
+</macro>
+
+<macro name="save_tweak" requires="servlet">
+	<n.if.visitor.is_site_admin>
+		<then.macro_editor. id="[n.current_command_id/]" base="[n.current_base_classes/]" breadcrumbs="[n.current_breadcrumbs/]">
+			<n.save contents="[n.get_parameter name='contents'/]"/>
+		</then.macro_editor.>
+	</n.if.visitor.is_site_admin>
+</macro>
+
+<macro name="command_path" requires="command_info">
+	<n.macro_viewer_path>
+		<id><n.use_text_encoder.id/></id>
+		<base><n.base/></base>
+		<breadcrumbs><n.naml_breadcrumbs/></breadcrumbs>
+	</n.macro_viewer_path>
+</macro>
+
+<macro name="invalid_command_html">
+	<n.naml_tools.>
+		<n.html>
+			<head>
+				<meta name="robots" content="noindex,nofollow"/>
+				<n.title.>Invalid Command</n.title.>
+			</head>
+			<body>
+				<n.macro_viewer_header.>
+					Invalid Command
+				</n.macro_viewer_header.>
+
+				<n.if.command_is_binary id="[n.current_command_id/]">
+					<then>
+						<h2>Command Not Found</h2>
+						Meaning ID: <n.current_command_id/>
+					</then>
+					<else>
+						<n.set_var. name="macro_name">
+							<n.command_name id="[n.current_command_id/]"/>
+						</n.set_var.>
+
+						The macro you are looking for could not be found (it may have been modified recently):
+						<div style="font-size:120%;margin:.6em">
+							<n.bold.var name="macro_name"/> in <i><n.command_source_name id="[n.current_command_id/]"/></i>
+						</div>
+
+						<n.macro_search. query="[n.var name='macro_name'/]" search_by="name">
+							<n.if.has_more_elements>
+								<then>
+									<div style="margin:1.5em 0 0">
+										Here you can find other related macros:
+									</div>
+									<n.macro_results_table/>
+								</then>
+							</n.if.has_more_elements>
+						</n.macro_search.>
+					</else>
+				</n.if.command_is_binary>
+			</body>
+		</n.html>
+	</n.naml_tools.>
+</macro>
+
+<macro name="macro_search_page" requires="servlet">
+	<n.naml_tools.>
+		<n.html>
+			<head>
+				<meta name="robots" content="noindex,follow"/>
+				<n.title.>Search Macros</n.title.>
+				<script type="text/javascript">
+					$(document).ready(function() {
+						var $input = $('#search_field');
+						$input.keydown(function(event) {
+							if (event.keyCode == 13) {
+								event.preventDefault();
+								$('form').submit();
+							}
+						});
+						$input.focus();
+					});
+				</script>
+			</head>
+			<body>
+				<n.macro_viewer_header.>
+					Macro Search
+				</n.macro_viewer_header.>
+
+				<n.if.is_empty.search_by_field.value>
+					<then.search_by_field.set_value value="name"/>
+				</n.if.is_empty.search_by_field.value>
+
+				<n.form. macro="macro_search_page" method="GET">
+					<img src="/images/search.png" class="image16"/>
+					<input id="search_field" type="text" size="25" name="query" value="[n.hide_null.macro_search_query/]"/>
+					<input class="toolbar action-button" type="submit" value="[t]Search[/t]"/>
+					<div style="clear:both;padding:.3em 0 0 1em">
+						<n.search_by_field.radio id="by_name" option_value="name"/>
+						<label for="by_name">Macro by name</label><br/>
+						<n.search_by_field.radio id="by_text" option_value="text"/>
+						<label for="by_text">Macro source contains</label><br/>
+					</div>
+				</n.form.>
+
+				<div style="margin-top:1em">
+					<n.macro_search_results query="[n.macro_search_query/]" search_by="[n.search_by_field.value/]"/>
+				</div>
+			</body>
+		</n.html>
+	</n.naml_tools.>
+</macro>
+
+<macro name="macro_search_results" parameters="query, search_by">
+	<n.macro_search. query="[n.query/]" search_by="[n.search_by/]">
+		<n.if.not.has_more_elements>
+			<then>
+				<n.if.not.is_null.macro_search_query>
+					<then>
+						<div class="big-title second-font">No macros found.</div>
+					</then>
+				</n.if.not.is_null.macro_search_query>
+			</then>
+			<else>
+				<div class="big-title second-font">
+					<n.element_count/> macro(s) found.
+				</div>
+				<n.macro_results_table/>
+			</else>
+		</n.if.not.has_more_elements>
+	</n.macro_search.>
+</macro>
+
+<macro name="macro_results_table" requires="command_list">
+	<n.put_in_head.>
+		<style type="text/css">
+			table.macro-results {
+				margin-top:.5em;
+				border-spacing: 0;
+			}
+			table.macro-results td {
+				padding: .4em 1.2em;
+			}
+		</style>
+	</n.put_in_head.>
+	<n.zebra_table_javascript table_selector="#macro-results"/>
+	<table id="macro-results" class="macro-results weak-color">
+		<tr class="shaded-bg-color bold">
+			<td>Macro Name</td>
+			<td>Requires</td>
+			<td>Source File</td>
+		</tr>
+		<n.loop.current_command.>
+			<tr style="[n.if.is_custom_tweak][then]font-weight:bold[/then][/n.if.is_custom_tweak]">
+				<td><a href="[n.command_path/]"><n.name/></a></td>
+				<td><em><n.hide_null.required_namespaces/></em></td>
+				<td><n.clean_source_name.source/></td>
+			</tr>
+		</n.loop.current_command.>
+	</table>
+</macro>
+
+<macro name="macro_search_query">
+	<n.get_parameter name="query"/>
+</macro>
+
+<macro name="current_command_id">
+	<n.get_parameter name="id"/>
+</macro>
+
+<macro name="current_base_classes">
+	<n.get_parameter name="base"/>
+</macro>
+
+<macro name="current_breadcrumbs">
+	<n.get_parameter name="breadcrumbs"/>
+</macro>
+
+<macro name="search_by_field" dot_parameter="do">
+	<n.field. name="search_by"><n.do/></n.field.>
+</macro>
+
+<macro name="compile_if_needed">
+	<n.if.not.is_compiled_all>
+		<then.run_compile_all/>
+	</n.if.not.is_compiled_all>
+</macro>
+
+<macro name="new_macro_page" requires="servlet">
+	<n.naml_tools.>
+		<n.html>
+			<head>
+				<meta name="robots" content="noindex,nofollow"/>
+				<n.title.>New Macro</n.title.>
+				<n.codemirror_shared_head/>
+				<script type="text/javascript">
+					<![CDATA[
+					var defaultMacroBody = '<macro name="">\n\n</'+'macro>';
+					$(document).ready(function() {
+						var $textarea = $('#txt_basic');
+						if ($textarea.val() == '')
+							$textarea.val(defaultMacroBody);
+						var canGoBack = history.length > 1;
+						if (canGoBack)
+							$('#go-back').show().before('<t>or</t> ');
+						inlineEditor('27em', 1, 13);
+
+						window.onbeforeunload = function() {
+							$textarea.val(basicEditor.getCode());
+						};
+					});
+
+					function saveChanges() {
+						notice('Saving... Please wait');
+						var call = '/template/NamlServlet.jtp?macro=save_tweak';
+						var code = basicEditor.getCode();
+						if (code.match(/^\s*$/) != null) {
+							notice('Error Found', 3000, 1500);
+							var msg = "Error: invalid macro code.";
+							var $errorBox = $('#error-box');
+							$errorBox.html(formatError(msg)).show();
+							if ($errorBox.height() > 150) {
+								$errorBox.css('overflow-y','scroll').height(150);
+							}
+							return;
+						}
+						var params = { contents: code };
+						$.post(call, params,
+							function(data) {
+								var result = eval('(' + data + ')');
+								if (result.error != null) {
+									notice('Error Found', 3000, 1500);
+									$('#error-box').html(formatError(result.error)).show();
+								} else {
+									var url = '/template/NamlServlet.jtp?macro=macro_viewer&id=' + result.macroId;
+									window.location = url;
+								}
+							}
+						);
+					};
+					]]>
+				</script>
+			</head>
+			<body>
+				<n.macro_viewer_header.>
+					New Macro
+				</n.macro_viewer_header.>
+
+				<n.important_notices/>
+
+				<div style="clear:both">
+					<n.macro_options_dropdown/>
+					<button id="saveButton" class="toolbar" style="font-weight:bold" onclick="saveChanges()">
+						Save Changes
+					</button>
+					<a id="go-back" href="javascript: void history.back()" style="display:none"><t>Go back</t></a>
+
+					<div style="clear:both">
+						<div id="error-box" class="error-message" style="padding:.5em;display:none"></div>
+						<textarea id="txt_basic" style="display:none"></textarea>
+					</div>
+				</div>
+			</body>
+		</n.html>
+	</n.naml_tools.>
+</macro>
+
+<macro name="macro_deleted_page" requires="servlet">
+	<n.naml_tools.>
+		<n.html>
+			<head>
+				<meta name="robots" content="noindex,nofollow"/>
+				<n.title.>Macro Deleted</n.title.>
+			</head>
+			<body>
+				<n.macro_viewer_header.>
+					Macro Deleted
+				</n.macro_viewer_header.>
+
+				<n.important_notices/>
+
+				<div style="clear:both">
+					<h2 style="padding-bottom:1em">
+						<img src="/images/success.png" class="image16"/>
+						Macro successfully deleted.
+					</h2>
+					<n.macro_options_dropdown/>
+				</div>
+
+				<br/>
+				<br/>
+			</body>
+		</n.html>
+	</n.naml_tools.>
+</macro>
+
+<macro name="new_macro_path">
+	<n.encode_url.>
+		/template/NamlServlet.jtp?macro=new_macro_page
+	</n.encode_url.>
+</macro>
+
+<macro name="macro_deleted_path">
+	<n.encode_url.>
+		/template/NamlServlet.jtp?macro=macro_deleted_page
+	</n.encode_url.>
+</macro>
\ No newline at end of file