<?xml version="1.0"?>
<feed xmlns="http://www.w3.org/2005/Atom" xml:lang="en">
	<id>https://wiki.secondlife.com/w/index.php?action=history&amp;feed=atom&amp;title=Recursive_URL_Substitution_Syntax</id>
	<title>Recursive URL Substitution Syntax - Revision history</title>
	<link rel="self" type="application/atom+xml" href="https://wiki.secondlife.com/w/index.php?action=history&amp;feed=atom&amp;title=Recursive_URL_Substitution_Syntax"/>
	<link rel="alternate" type="text/html" href="https://wiki.secondlife.com/w/index.php?title=Recursive_URL_Substitution_Syntax&amp;action=history"/>
	<updated>2026-07-27T15:45:43Z</updated>
	<subtitle>Revision history for this page on the wiki</subtitle>
	<generator>MediaWiki 1.42.1</generator>
	<entry>
		<id>https://wiki.secondlife.com/w/index.php?title=Recursive_URL_Substitution_Syntax&amp;diff=27110&amp;oldid=prev</id>
		<title>Phoenix Linden: /* Strings */</title>
		<link rel="alternate" type="text/html" href="https://wiki.secondlife.com/w/index.php?title=Recursive_URL_Substitution_Syntax&amp;diff=27110&amp;oldid=prev"/>
		<updated>2007-08-03T18:24:56Z</updated>

		<summary type="html">&lt;p&gt;&lt;span dir=&quot;auto&quot;&gt;&lt;span class=&quot;autocomment&quot;&gt;Strings&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;
&lt;table style=&quot;background-color: #fff; color: #202122;&quot; data-mw=&quot;interface&quot;&gt;
				&lt;col class=&quot;diff-marker&quot; /&gt;
				&lt;col class=&quot;diff-content&quot; /&gt;
				&lt;col class=&quot;diff-marker&quot; /&gt;
				&lt;col class=&quot;diff-content&quot; /&gt;
				&lt;tr class=&quot;diff-title&quot; lang=&quot;en&quot;&gt;
				&lt;td colspan=&quot;2&quot; style=&quot;background-color: #fff; color: #202122; text-align: center;&quot;&gt;← Older revision&lt;/td&gt;
				&lt;td colspan=&quot;2&quot; style=&quot;background-color: #fff; color: #202122; text-align: center;&quot;&gt;Revision as of 11:24, 3 August 2007&lt;/td&gt;
				&lt;/tr&gt;&lt;tr&gt;&lt;td colspan=&quot;2&quot; class=&quot;diff-lineno&quot; id=&quot;mw-diff-left-l22&quot;&gt;Line 22:&lt;/td&gt;
&lt;td colspan=&quot;2&quot; class=&quot;diff-lineno&quot;&gt;Line 22:&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class=&quot;diff-marker&quot;&gt;&lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;| &amp;#039;agent-id&amp;#039;:foo, &amp;#039;item-id&amp;#039;:bar&lt;/div&gt;&lt;/td&gt;&lt;td class=&quot;diff-marker&quot;&gt;&lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;| &amp;#039;agent-id&amp;#039;:foo, &amp;#039;item-id&amp;#039;:bar&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class=&quot;diff-marker&quot;&gt;&lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;| agent/foo/inventory/item/bar&lt;/div&gt;&lt;/td&gt;&lt;td class=&quot;diff-marker&quot;&gt;&lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;| agent/foo/inventory/item/bar&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td colspan=&quot;2&quot; class=&quot;diff-side-deleted&quot;&gt;&lt;/td&gt;&lt;td class=&quot;diff-marker&quot; data-marker=&quot;+&quot;&gt;&lt;/td&gt;&lt;td style=&quot;color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #a3d3ff; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;&lt;ins style=&quot;font-weight: bold; text-decoration: none;&quot;&gt;|}&lt;/ins&gt;&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td colspan=&quot;2&quot; class=&quot;diff-side-deleted&quot;&gt;&lt;/td&gt;&lt;td class=&quot;diff-marker&quot; data-marker=&quot;+&quot;&gt;&lt;/td&gt;&lt;td style=&quot;color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #a3d3ff; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;&lt;ins style=&quot;font-weight: bold; text-decoration: none;&quot;&gt;&lt;/ins&gt;&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td colspan=&quot;2&quot; class=&quot;diff-side-deleted&quot;&gt;&lt;/td&gt;&lt;td class=&quot;diff-marker&quot; data-marker=&quot;+&quot;&gt;&lt;/td&gt;&lt;td style=&quot;color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #a3d3ff; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;&lt;ins style=&quot;font-weight: bold; text-decoration: none;&quot;&gt;Values which are lists/tuples will have their elements urlquoted and joined with &#039;/&#039;.  I.e. they are assumed to be exploded paths.  E.g.:&lt;/ins&gt;&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td colspan=&quot;2&quot; class=&quot;diff-side-deleted&quot;&gt;&lt;/td&gt;&lt;td class=&quot;diff-marker&quot; data-marker=&quot;+&quot;&gt;&lt;/td&gt;&lt;td style=&quot;color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #a3d3ff; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;&lt;ins style=&quot;font-weight: bold; text-decoration: none;&quot;&gt;&lt;/ins&gt;&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td colspan=&quot;2&quot; class=&quot;diff-side-deleted&quot;&gt;&lt;/td&gt;&lt;td class=&quot;diff-marker&quot; data-marker=&quot;+&quot;&gt;&lt;/td&gt;&lt;td style=&quot;color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #a3d3ff; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;&lt;ins style=&quot;font-weight: bold; text-decoration: none;&quot;&gt;{| border=&quot;1&quot;&lt;/ins&gt;&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td colspan=&quot;2&quot; class=&quot;diff-side-deleted&quot;&gt;&lt;/td&gt;&lt;td class=&quot;diff-marker&quot; data-marker=&quot;+&quot;&gt;&lt;/td&gt;&lt;td style=&quot;color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #a3d3ff; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;&lt;ins style=&quot;font-weight: bold; text-decoration: none;&quot;&gt;! Format !! Map Contents !! Result&lt;/ins&gt;&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td colspan=&quot;2&quot; class=&quot;diff-side-deleted&quot;&gt;&lt;/td&gt;&lt;td class=&quot;diff-marker&quot; data-marker=&quot;+&quot;&gt;&lt;/td&gt;&lt;td style=&quot;color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #a3d3ff; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;&lt;ins style=&quot;font-weight: bold; text-decoration: none;&quot;&gt;|-&lt;/ins&gt;&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td colspan=&quot;2&quot; class=&quot;diff-side-deleted&quot;&gt;&lt;/td&gt;&lt;td class=&quot;diff-marker&quot; data-marker=&quot;+&quot;&gt;&lt;/td&gt;&lt;td style=&quot;color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #a3d3ff; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;&lt;ins style=&quot;font-weight: bold; text-decoration: none;&quot;&gt;| &amp;lt;code&amp;gt;foo/{$stuff}/baz&amp;lt;/code&amp;gt;&lt;/ins&gt;&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td colspan=&quot;2&quot; class=&quot;diff-side-deleted&quot;&gt;&lt;/td&gt;&lt;td class=&quot;diff-marker&quot; data-marker=&quot;+&quot;&gt;&lt;/td&gt;&lt;td style=&quot;color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #a3d3ff; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;&lt;ins style=&quot;font-weight: bold; text-decoration: none;&quot;&gt;| &amp;lt;code&amp;gt;&#039;stuff&#039;:[&#039;one&#039;,&#039;two&#039;,&#039;three&#039;]&amp;lt;/code&amp;gt;&lt;/ins&gt;&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td colspan=&quot;2&quot; class=&quot;diff-side-deleted&quot;&gt;&lt;/td&gt;&lt;td class=&quot;diff-marker&quot; data-marker=&quot;+&quot;&gt;&lt;/td&gt;&lt;td style=&quot;color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #a3d3ff; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;&lt;ins style=&quot;font-weight: bold; text-decoration: none;&quot;&gt;| &amp;lt;code&amp;gt;foo/one/two/three/baz&amp;lt;/code&amp;gt;&lt;/ins&gt;&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class=&quot;diff-marker&quot;&gt;&lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;|}&lt;/div&gt;&lt;/td&gt;&lt;td class=&quot;diff-marker&quot;&gt;&lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;|}&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class=&quot;diff-marker&quot;&gt;&lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;br&gt;&lt;/td&gt;&lt;td class=&quot;diff-marker&quot;&gt;&lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;br&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;/table&gt;</summary>
		<author><name>Phoenix Linden</name></author>
	</entry>
	<entry>
		<id>https://wiki.secondlife.com/w/index.php?title=Recursive_URL_Substitution_Syntax&amp;diff=27109&amp;oldid=prev</id>
		<title>Phoenix Linden: /* c++ */</title>
		<link rel="alternate" type="text/html" href="https://wiki.secondlife.com/w/index.php?title=Recursive_URL_Substitution_Syntax&amp;diff=27109&amp;oldid=prev"/>
		<updated>2007-08-03T18:24:23Z</updated>

		<summary type="html">&lt;p&gt;&lt;span dir=&quot;auto&quot;&gt;&lt;span class=&quot;autocomment&quot;&gt;c++&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;
&lt;table style=&quot;background-color: #fff; color: #202122;&quot; data-mw=&quot;interface&quot;&gt;
				&lt;col class=&quot;diff-marker&quot; /&gt;
				&lt;col class=&quot;diff-content&quot; /&gt;
				&lt;col class=&quot;diff-marker&quot; /&gt;
				&lt;col class=&quot;diff-content&quot; /&gt;
				&lt;tr class=&quot;diff-title&quot; lang=&quot;en&quot;&gt;
				&lt;td colspan=&quot;2&quot; style=&quot;background-color: #fff; color: #202122; text-align: center;&quot;&gt;← Older revision&lt;/td&gt;
				&lt;td colspan=&quot;2&quot; style=&quot;background-color: #fff; color: #202122; text-align: center;&quot;&gt;Revision as of 11:24, 3 August 2007&lt;/td&gt;
				&lt;/tr&gt;&lt;tr&gt;&lt;td colspan=&quot;2&quot; class=&quot;diff-lineno&quot; id=&quot;mw-diff-left-l120&quot;&gt;Line 120:&lt;/td&gt;
&lt;td colspan=&quot;2&quot; class=&quot;diff-lineno&quot;&gt;Line 120:&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class=&quot;diff-marker&quot;&gt;&lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;* string substitution&lt;/div&gt;&lt;/td&gt;&lt;td class=&quot;diff-marker&quot;&gt;&lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;* string substitution&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class=&quot;diff-marker&quot;&gt;&lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;* url substitution&lt;/div&gt;&lt;/td&gt;&lt;td class=&quot;diff-marker&quot;&gt;&lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;* url substitution&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td colspan=&quot;2&quot; class=&quot;diff-side-deleted&quot;&gt;&lt;/td&gt;&lt;td class=&quot;diff-marker&quot; data-marker=&quot;+&quot;&gt;&lt;/td&gt;&lt;td style=&quot;color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #a3d3ff; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;&lt;ins style=&quot;font-weight: bold; text-decoration: none;&quot;&gt;&lt;/ins&gt;&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td colspan=&quot;2&quot; class=&quot;diff-side-deleted&quot;&gt;&lt;/td&gt;&lt;td class=&quot;diff-marker&quot; data-marker=&quot;+&quot;&gt;&lt;/td&gt;&lt;td style=&quot;color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #a3d3ff; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;&lt;ins style=&quot;font-weight: bold; text-decoration: none;&quot;&gt;== perl ==&lt;/ins&gt;&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td colspan=&quot;2&quot; class=&quot;diff-side-deleted&quot;&gt;&lt;/td&gt;&lt;td class=&quot;diff-marker&quot; data-marker=&quot;+&quot;&gt;&lt;/td&gt;&lt;td style=&quot;color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #a3d3ff; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;&lt;ins style=&quot;font-weight: bold; text-decoration: none;&quot;&gt;In &amp;lt;code&amp;gt;Indra::WebServices&amp;lt;/code&amp;gt;, you can call &amp;lt;code&amp;gt;buildService($service_name)&amp;lt;/code&amp;gt; to make a client to that service. The current implementation supports:&lt;/ins&gt;&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td colspan=&quot;2&quot; class=&quot;diff-side-deleted&quot;&gt;&lt;/td&gt;&lt;td class=&quot;diff-marker&quot; data-marker=&quot;+&quot;&gt;&lt;/td&gt;&lt;td style=&quot;color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #a3d3ff; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;&lt;ins style=&quot;font-weight: bold; text-decoration: none;&quot;&gt;* string substitution&lt;/ins&gt;&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td colspan=&quot;2&quot; class=&quot;diff-side-deleted&quot;&gt;&lt;/td&gt;&lt;td class=&quot;diff-marker&quot; data-marker=&quot;+&quot;&gt;&lt;/td&gt;&lt;td style=&quot;color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #a3d3ff; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;&lt;ins style=&quot;font-weight: bold; text-decoration: none;&quot;&gt;* query string substitution&lt;/ins&gt;&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td colspan=&quot;2&quot; class=&quot;diff-side-deleted&quot;&gt;&lt;/td&gt;&lt;td class=&quot;diff-marker&quot; data-marker=&quot;+&quot;&gt;&lt;/td&gt;&lt;td style=&quot;color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #a3d3ff; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;&lt;ins style=&quot;font-weight: bold; text-decoration: none;&quot;&gt;* recursive substitution&lt;/ins&gt;&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;/table&gt;</summary>
		<author><name>Phoenix Linden</name></author>
	</entry>
	<entry>
		<id>https://wiki.secondlife.com/w/index.php?title=Recursive_URL_Substitution_Syntax&amp;diff=25404&amp;oldid=prev</id>
		<title>Phoenix Linden: New page: Like any substitution syntax, using untrusted formatted strings or untrusted sources of data can lead to exploits. Be careful when designing the usage so that no tainted input winds up in ...</title>
		<link rel="alternate" type="text/html" href="https://wiki.secondlife.com/w/index.php?title=Recursive_URL_Substitution_Syntax&amp;diff=25404&amp;oldid=prev"/>
		<updated>2007-07-12T19:51:05Z</updated>

		<summary type="html">&lt;p&gt;New page: Like any substitution syntax, using untrusted formatted strings or untrusted sources of data can lead to exploits. Be careful when designing the usage so that no tainted input winds up in ...&lt;/p&gt;
&lt;p&gt;&lt;b&gt;New page&lt;/b&gt;&lt;/p&gt;&lt;div&gt;Like any substitution syntax, using untrusted formatted strings or untrusted sources of data can lead to exploits. Be careful when designing the usage so that no tainted input winds up in the context.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
= Syntax =&lt;br /&gt;
The syntax is based on placing curly braces inside an URL to indicate that the curly brace and everything inside should be replaced with a substitution. Each type of substitution will have it&amp;#039;s own rules but every time you see { and } then all contents inside those braces are to be replaced.&lt;br /&gt;
&lt;br /&gt;
== Strings ==&lt;br /&gt;
String substitution uses an open curly brace &amp;#039;{&amp;#039; followed by a dollar symbol &amp;#039;$&amp;#039; followed by the name of the substitution and a closing curly brace &amp;#039;}&amp;#039;. The name is used as a key into a map whose value will be replaced into the original format string. The key must only contain alphanumeric characters and &amp;#039;+&amp;#039;, &amp;#039;-&amp;#039;, &amp;#039;_&amp;#039;, and spaces.&lt;br /&gt;
&lt;br /&gt;
Values which appear in the map but not referenced in the format string are ignored.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
{| border=&amp;quot;1&amp;quot;&lt;br /&gt;
|+ String Substitution Examples&lt;br /&gt;
! Format !! Map Contents !! Result&lt;br /&gt;
|-&lt;br /&gt;
| {$bucket}.agent.lindenlab.com&lt;br /&gt;
| &amp;#039;bucket&amp;#039;:&amp;#039;a&amp;#039;&lt;br /&gt;
| a.agent.lindenlab.com&lt;br /&gt;
|-&lt;br /&gt;
| agent/{$agent-id}/inventory/item/{$item-id}&lt;br /&gt;
| &amp;#039;agent-id&amp;#039;:foo, &amp;#039;item-id&amp;#039;:bar&lt;br /&gt;
| agent/foo/inventory/item/bar&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== Query Strings ==&lt;br /&gt;
Query strings are a specialized url syntax for representing the contents of a map as an ampersand delimited url query string including the leading &amp;#039;?&amp;#039;. Query string use an open curly brace &amp;#039;{&amp;#039; followed by a percent symbol &amp;#039;%&amp;#039; followed by the name of a dictionary in the replacement context followed by a closing curly brace &amp;#039;}&amp;#039;.&lt;br /&gt;
&lt;br /&gt;
Unlike string substitution, if the named value is not a key in the map contents, the russ directive will be stripped.&lt;br /&gt;
&lt;br /&gt;
{| border=&amp;quot;1&amp;quot;&lt;br /&gt;
|+ Query String Substitution Examples&lt;br /&gt;
! Format !! Map Contents !! Result&lt;br /&gt;
|-&lt;br /&gt;
| /sql/{$query}{%params}&lt;br /&gt;
| { &amp;#039;query&amp;#039;:&amp;#039;get-agent-name-by-id&amp;#039;, &amp;#039;params&amp;#039;:{&amp;#039;agent_id&amp;#039;:123}}&lt;br /&gt;
| /sql/get-agent-name-by-id?agent_id=123&lt;br /&gt;
|-&lt;br /&gt;
| /proc/{$proc}{%params}&lt;br /&gt;
| { &amp;#039;proc&amp;#039;:&amp;#039;messages/dir/DirFindPeople&amp;#039;, &amp;#039;params&amp;#039;:{&amp;#039;estate&amp;#039;:1, &amp;#039;query&amp;#039;:&amp;#039;designer clothing&amp;#039;}}&lt;br /&gt;
| /proc/messages/dir/DirFindPeople?estate=1&amp;amp;query=designer+clothing&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== Functions ==&lt;br /&gt;
Function substitution uses an open curly brace &amp;#039;{&amp;#039; followed by a bang symbol &amp;#039;!&amp;#039; followed by the name of the substitution function and a closing curly brace &amp;#039;}&amp;#039;. The name is a function that is available to the substitution engine, and may be implementation specific. The function is prototyped as accepting a map context and returning a string.&lt;br /&gt;
&lt;br /&gt;
For example, &amp;lt;b&amp;gt;{!region-host-port}&amp;lt;/b&amp;gt; could be a function which takes a map which is assumed to contain a key &amp;lt;code&amp;gt;&amp;#039;region-id&amp;#039;&amp;lt;/code&amp;gt;. The function will perform a service lookup for region presence with the region-id in the service builder, and then parse the return document for the region host and port.&lt;br /&gt;
&lt;br /&gt;
== REST Requests ==&lt;br /&gt;
For REST Request substitution, the embedded URL is fetched, parsed for a single [[LLSD]] document which is embedded inside the curly braces. &lt;br /&gt;
&lt;br /&gt;
The simple syntax is an opening curly brace &amp;#039;{&amp;#039;, followed by the URL, and terminated with a closing curly brace &amp;#039;}&amp;#039;. The document at the url is parsed and treated as a string. Containers, the undefined element, and non-parseable documents are considered errors.&lt;br /&gt;
&lt;br /&gt;
For http request, no instructions to the protocol means to perform a normal GET.&lt;br /&gt;
&lt;br /&gt;
{| border=&amp;quot;1&amp;quot;&lt;br /&gt;
|+ Rest Request Substitution Examples&lt;br /&gt;
! Format !! Results&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;nowiki&amp;gt;{http://gridtool.agni.lindenlab.com/agents/online-now}&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
| 58582&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;nowiki&amp;gt;{http://blondie.lindenlab.com/lookup/agentname/phoenix/linden||agent-id}&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
| 3c115e51-04f4-523c-9fa6-98aff1034730&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Supported protocols: http, https &lt;br /&gt;
&lt;br /&gt;
We should probably support file.&lt;br /&gt;
&lt;br /&gt;
== Recursive Substitution ==&lt;br /&gt;
In theory, this grammar can be used recursively, though only python currently supports this feature.&lt;br /&gt;
&lt;br /&gt;
{| border=&amp;quot;1&amp;quot;&lt;br /&gt;
|+ Formating Examples&lt;br /&gt;
! Format&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;nowiki&amp;gt;{http://sim1028.{$grid}.{$domain}/agent/{$agent-id}/location}&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
| {{$node}{$domain}}&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
= Syntax Specification =&lt;br /&gt;
The full syntax is an opening curly brace &amp;#039;{&amp;#039;, followed by the URL, followed by a vline &amp;#039;|&amp;#039;, followed by protocol specific instructions, followed by a &amp;#039;vline&amp;#039;, followed by a path to follow through the document to the element which will be treated as a string. &lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
russ-statement : open-russ substitution close-russ&lt;br /&gt;
open-russ: &amp;#039;{&amp;#039;&lt;br /&gt;
close-russ: &amp;#039;}&amp;#039;&lt;br /&gt;
substituion: string-substitution| query-string-substitution | url-substitution | function-substitution&lt;br /&gt;
string-substition: &amp;#039;$&amp;#039; llsd-key&lt;br /&gt;
query-string-substition: &amp;#039;%&amp;#039; llsd-key&lt;br /&gt;
function-substitution: &amp;#039;!&amp;#039; function-name&lt;br /&gt;
function-name: llsd-key&lt;br /&gt;
url-substitution: url [ vline [ url-parameters ] vline llsd-path]&lt;br /&gt;
url: protocol &amp;#039;:&amp;#039; (normal url authority &amp;amp; host &amp;amp; path &amp;amp; parameters &amp;amp; opaque parts)&lt;br /&gt;
protocol: &amp;#039;http&amp;#039; | &amp;#039;https&amp;#039;&lt;br /&gt;
vline: &amp;#039;|&amp;#039;&lt;br /&gt;
url-parameters: verb [ body ]&lt;br /&gt;
verb: &amp;#039;GET&amp;#039; | &amp;#039;PUT&amp;#039; | &amp;#039;POST&amp;#039; | &amp;#039;DELETE&amp;#039;&lt;br /&gt;
body: ???&lt;br /&gt;
llsd-path: segment * [ &amp;quot;/&amp;quot; segment ]&lt;br /&gt;
segment: llsd-key&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Please note that the following elements in the syntax rules are not well defined:&lt;br /&gt;
* llsd-key&lt;br /&gt;
* body&lt;br /&gt;
* function-name&lt;br /&gt;
&lt;br /&gt;
= Implementations =&lt;br /&gt;
== python ==&lt;br /&gt;
Our indra python libs have a russ implementation in russ.py which supports:&lt;br /&gt;
* string substitution&lt;br /&gt;
* query string substitution&lt;br /&gt;
* url substitution&lt;br /&gt;
* recursive substitution&lt;br /&gt;
&lt;br /&gt;
== c++ ==&lt;br /&gt;
In indra/llmessage libs has a russ implementation inside of the LLServiceBuilder class which supports:&lt;br /&gt;
* string substitution&lt;br /&gt;
* url substitution&lt;/div&gt;</summary>
		<author><name>Phoenix Linden</name></author>
	</entry>
</feed>