Look for the whereToSearch attribute within the searchPatterns tag.
This section covers the common and advanced techniques that create and edit server behaviors. Most of the suggestions involve specific settings in the EDML files.
Finding server behaviors
You can find server behaviors by:
Writing search patterns
Using optional search patterns
Writing search patterns
To update or delete server behaviors, provide a way for Dreamweaver to find each instance in a document. It requires a quickSearch tag and at least one searchPattern tag, which is contained within the searchPatterns tag.
The quickSearch tag must be a string, not a regular expression, that indicates that the server behavior exists on the page. It is not case-sensitive. It must be short and unique, and it must avoid spaces and other sections that the user can change. The following example shows a participant that consists of the simple ASP JavaScript tag:
<% if (Recordset1.EOF) Response.Redirect("some_url_here") %>
In the following example, the quickSearch string checks for that tag:
<quickSearch>Response.Redirect</quickSearch>
For performance reasons, the quickSearch pattern is the beginning of the process of finding server behavior instances. If this string is found in the document and the participant identifies a server behavior (in the group file, partType="identifier" for this participant), the related server behavior files are loaded and the findServerBehaviors() function is called. If your participant has no reliable strings for which to search (or for debugging purposes), you can leave the quickSearch string empty, as shown in the following example:
<quickSearch></quickSearch>
In this example, the server behavior is always loaded and can search the document.
Next, the searchPattern tag searches the document more precisely than the quickSearch tag and extracts parameter values from the participant code. The search patterns specify where to search (the whereToSearch attribute) with a series of searchPattern tags that contain specific patterns. These patterns can use simple strings or regular expressions. The previous example code is an ASP directive. So the whereToSearch="directive" specification and a regular expression identify the directive and extract the parameters, as shown in the following example:
<quickSearch>Response.Write</quickSearch> <searchPatterns whereToSearch="directive"> <searchPattern paramNames="rs,new__url"> /if\s*\((\w+)\.EOF\)\s*Response\.Redirect\("([^\r\n]*)"\)/i </searchPattern> </searchPatterns>
The search string is defined as a regular expression by starting and ending with a slash (/). An i follows the slash, which means that it is not case-sensitive. Within the regular expression, special characters such as parentheses () and periods (.) are escaped by preceding them with a backslash (\). The two parameters rs and new_url are extracted from the string by using parenthetical subexpressions (the parameters must be enclosed in parentheses). In this example, (\w+) and ([^\r\n]*) indicate the parameters. These values correspond to the regular expression values that $1 and $2 normally returns.
Optional search patterns
Sometimes you want to identify a participant even if some parameters are not found. The participant stores some optional information such as a telephone number. For such an example, you could use the following ASP code:
<% //address block LNAME = "joe"; FNAME = "smith"; PHONE = "123-4567"; %>
You could use the following search patterns:
<quickSearch>address</quickSearch> <searchPatterns whereToSearch="directive"> <searchPattern paramNames="lname">/LNAME\s*=\s*"([^\r\n]*)"/i</searchPattern> <searchPattern paramNames="fname">/FNAME\s*=\s*"([^\r\n]*)"/i</searchPattern> <searchPattern paramNames="phone">/PHONE\s*=\s*"([^\r\n]*)"/i</searchPattern> </searchPatterns>
In the previous example, the telephone number must be specified. However, you can make the telephone number optional, by adding the isOptional attribute, as shown in the following example:
<quickSearch>address</quickSearch> <searchPatterns whereToSearch="directive"> <searchPattern paramNames="lname">/LNAME\s*=\s*"([^\r\n]*)"/i</searchPattern> <searchPattern paramNames="fname">/FNAME\s*=\s*"([^\r\n]*)"/i</searchPattern> <searchPattern paramNames="phone" isOptional="true">/PHONE\s*=\s*"([^\r\n]*)"/i¬ </searchPattern> </searchPatterns>
Now the participant is recognized, even if the telephone number is not found.
How participants are matched
If a server behavior has more than one participant, the participants must be identified in the user document and matched. If the user applies multiple instances of the server behavior to a document, each group of participants must be matched accordingly. To ensure that participants are matched correctly, change or add parameters and construct participants so they can be uniquely identified.
Matching requires some rules. Participants are matched when all parameters with the same name have the same value. Above and below the html tag, there can be only one instance of a participant with a given set of parameter values. Within the html.../html tags, Dreamwaever matches participants by their position relative to the selection or to common nodes that are used for insertion.
Participants without parameters are automatically matched, as shown in the following example of a server behavior with group file:
<group serverBehavior="test.htm"> <title>Test</title> <groupParticipants> <groupParticipant name="test_p1" partType="identifier" /> <groupParticipant name="test_p2" partType="identifier" /> </groupParticipants> </group>
The following example inserts two simple participants above the html tag:
<% //test_p1 %> <% //test_p2 %> <html>
These participants are found and matched, and Test appears once in the Server Behaviors panel. If you add the server behavior again, nothing is added because the participants exist.
If the participants have unique parameters, multiple instances can be inserted above the html tag. For example, by adding a name parameter to the participant, a user can enter a unique name in the Test Server Behavior dialog box. If the user enters the name aaa, the following participants are inserted:
If you add the server behavior again with a different name, such as bbb, the document now looks like the following example:
<% //test_p1 name="aaa" %> <% //test_p2 name="aaa" %> <html>
Two instances of Test are listed in the Server Behaviors panel. If the user tries to add a third instance to the page and names it aaa, nothing is added because it exists.
Within the html tag, matching can also use position information. In the following example, you have two participants, one that is added before the selection and another that is added after the selection:
<% if (expression) { //mySBName %>
Random HTML selection here:
<% } //end mySBName %>
These two participants are without parameters, so they are grouped. However, you can add another instance of this server behavior elsewhere in the HTML, as shown in the following example:
<% if (expression) { //mySBName %>
Random HTML selection here:
<% } //end mySBName %>
More HTML here:
<% if (expression) { //mySBName %>
Another HTML selection here:
<% } //end mySBName %>
Now, you have two identical instances of each participant, which is allowed within the HTML. Dreamweaver matches them by the order in which they occur in the document.
The following example shows a matching problem and how to avoid it. You can create a participant that computes the tax on some dynamic data and displays the result at the selection.
<% total = Recordset1.Fields.Item("itemPrice").Value * 1.0825 %> <html> <body> The total (with taxes) is $<%=total%> </body> </html>
The two participants are matched because they have no common parameters. However, if you add a second instance of this server behavior, you must have the following code:
<% total = Recordset1.Fields.Item("itemPrice").Value * 1.0825 %> <% total = Recordset1.Fields.Item("salePrice").Value * 1.0825 %> <html> <body> The total0(with taxes) is $<%=total%> Sale price (with taxes) is $<%=total%> </body> </html>
This server behavior no longer works correctly because only one parameter is named total. To solve this problem, make sure that a parameter with a unique value exists and that it can be used to match the participants. In the following example, you could make the total variable name unique using the column name:
<% itemPrice_total = Recordset1.Fields.Item("itemPrice").Value * 1.0825 %> <% salePrice_total = Recordset1.Fields.Item("salePrice").Value * 1.0825 %> <html> <body> The total0(with taxes) is $<%=itemPrice_total%> Sale price (with taxes) is $<%=salePrice_total%> </body> </html>
The search patterns now uniquely identify and match the participants.
Search pattern resolution
Dreamweaver supports the following actions by using the participant searchPatterns functionality:
File transfer dependency
Updating the file paths for any file reference (such as those for include files)
When Dreamweaver creates server models, it builds lists of patterns by scanning all the participants for special paramNames attributes. To find URLs to check file dependency and to fix the pathname, Dreamweaver uses each searchPattern tag in which one of the paramNames attribute ends with _url. Multiple URLs can be specified in a single searchPattern tag.
For each translator searchPattern tag that has a paramNames attribute value that ends with _includeUrl, Dreamweaver uses that searchPattern tag to translate include file statements on the page. Dreamweaver uses a different suffix string to identify include file URLs because not all URL references are translated. Also, only a single URL can be translated as an include file.
In resolving a searchPatterns tag, Dreamweaver uses the following algorithm:
-
-
If the attribute value starts with tag+, the remaining string is assumed to be the tag name (no spaces are allowed in the tag name).
-
Look for the limitSearch attribute within the searchPattern tag.
-
If the attribute value starts with attribute+, the remaining string is assumed to be the attribute name (no spaces are allowed in the attribute name).
If these four steps are successful, Dreamweaver assumes a tag/attribute combination. Otherwise, Dreamweaver starts looking for searchPattern tags with a paramName attribute that has a _url suffix and a regular expression that is defined. (For information about regular expressions, see Regular expressions.)
The following example of a searchPatterns tag has no search pattern because it combines a tag (cfinclude) with an attribute (template) to isolate the URL for dependency file checking, path fixing, and so forth:
<searchPatterns whereToSearch="tag+cfinclude"> <searchPattern paramNames="include_url" limitSearch="attribute+template" /> </searchPatterns>
The tag/attribute combination (see the previous example) does not apply to translation because Dreamweaver always translates to straight text in the JavaScript layer. File dependency checking, path fixing, and so on occurs in the C layer. In the C layer, Dreamweaver internally splits the document into directives (straight text) and tags (parsed into an efficient tree structure).
Update server behaviors
You can update server behaviors by:
Replacement update
Precision update
Replacement update
By default, participant EDML files do not have an <updatePatterns> tag, and instances of the participant are updated in the document by replacing them entirely. When a user edits an existing server behavior and clicks OK, any participant that contains a parameter whose value has changed is removed. Then, the participant is reinserted with the new value in the same location.
If the user customizes participant code in the document, the participant might not be recognized if the search patterns look for the old code. Shorter search patterns can let the user customize the participant code in their document. However, updating the server behavior instance can cause the replacement of the participant, which loses the custom edits.
Precision update
In some cases, it is desirable to let users customize the participant code after it is inserted in the document. This situation can be achieved by limiting the search patterns and providing update patterns in the EDML file. After you add the participant to the page, the server behavior updates only specific parts of it. The following example shows a simple participant with two parameters:
<% if (Recordset1.EOF) Response.Redirect("some_url_here") %>
This example might use the following search patterns:
<quickSearch>Response.Write</quickSearch> <searchPatterns whereToSearch="directive"> <searchPattern paramNames="rs,new__url"> /if\s*\((\w+)\.EOF\)\s*Response\.Redirect\("([^\r\n]*)"\)/i </searchPattern> </searchPatterns>
The user could add another test to a particular instance of this code, as shown in the following example:
<% if (Recordset1.EOF || x > 2) Response.Redirect("some_url_here") %>
The search patterns fail because they are looking for a parenthesis after the EOF parameter. To make the search patterns more forgiving, you can shorten them by splitting them up, as shown in the following example:
<quickSearch>Response.Write</quickSearch> <searchPatterns whereToSearch="directive"> <searchPattern paramNames="rs">/(\w+)\.EOF/</searchPattern> <searchPattern paramNames="new__url"> /if\s*\([^\r\n]*\)\s*Response\.Redirect\("([^\r\n]*)"/i </searchPattern> </searchPatterns>
These shortened search patterns are flexible, so the user can add to the code. However, if the server behavior changes the URL when the user clicks OK, the participant is replaced and the customizations are lost. To update more precisely, add an updatePatterns tag that contains a pattern for updating each parameter:
<updatePatterns> <updatePattern paramNames="rs">/(\b)\w+(\.EOF)/\</updatePattern> <updatePattern paramNames="new__url"> /(Response\.Redirect\(")[^\r\n]*(")/i </updatePattern> </updatePatterns>
In update patterns, the parentheses are reversed and are placed around the text before and after the parameter. For search patterns, use the textBeforeParam(param)textAfterParam parameter. For update patterns, use the (textBeforeParam)param(textAfterParam) parameter. All the text between the two parenthetical subexpressions is replaced with the new value for the parameter.
Delete server behaviors
You can delete server behaviors by:
Default deletion and dependency counts
Using delete flags to limit participant deletion
Default deletion and dependency counts
The user can delete an instance that is selected in the Server Behaviors panel by clicking the Minus (-) button or pressing Delete. All the participants are removed except for the ones that other server behaviors share. Specifically, if more than one server behavior has a participant pointer to the same node, the node is not deleted.
By default, participants are deleted by removing an entire tag. If the insert location is wrapSelection, only the outer tag is removed. For attributes, the entire attribute declaration is removed. The following example shows an attribute participant on the ACTION attribute of a form tag:
<form action="<% my_participant %>">
After deleting the attribute, only form remains.
Using delete flags to limit participant deletion
To limit the way that participants are deleted, add a delete tag to the EDML file. The following example shows a participant that is an href attribute of a link:
<a href="<%=MY_URL%>">Link Text</a>
When this attribute participant is deleted, the resulting tag is <a>Link Text</a>, which no longer appears as a link in Dreamweaver. Deleting only the attribute value is preferred. Deletion is done by adding the following tag to the participant EDML file:
<delete deleteType="innerOnly"/>
Another approach is to remove the entire tag; typing <delete deleteType="tagOnly"/> deletes the attribute. The resulting text is Link Text.
Share-in-memory JavaScript files
If several HTML files reference a particular JavaScript file, Dreamweaver loads the JavaScript into a central location where the HTML files can share the same JavaScript source. These files contain the following line:
//SHARE-IN-MEMORY=true
If a JavaScript file has the SHARE-IN-MEMORY directive and an HTML file references it (by using the SCRIPT tag with the SRC attribute), Dreamweaver loads the JavaScript into a memory location where the code is implicitly included in all HTML files thereafter.
Because JavaScript files that are loaded into this central location share memory, the files cannot duplicate any declarations. If a share-in-memory file defines a variable or function and any other JavaScript file defines the same variable or function, a name conflict occurs. When writing new JavaScript files, be aware of these files and their naming conventions.