4D v164D Transformation Tags |
|||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
4D v16
4D Transformation Tags
4D Transformation Tags
4D provides a set of transformation tags which allow you to insert references to 4D variables or expressions, or to perform different types of processing within a source text, referred to as a "template". These tags are interpreted when the source text is executed and generate an output text. This principle is used in particular by the 4D Web server to build the Semi-dynamic pages. These tags are generally be inserted as HTML type comments (<!--#Tag Contents--> ). However, other comments such as <!--Beginning of list--> are also possible. It is possible to mix several types of tags. For example, the following HTML structure is entirely feasible:
<HTML> ... <BODY> <!--#4DSCRIPT/PRE_PROCESS--> (Method call) <!--#4DIF (myvar=1)--> (If condition) <!--#4DINCLUDE banner1.html--> (Subpage insertion) <!--#4DENDIF--> (End if) <!--#4DIF (mtvar=2)--> <!--#4DINCLUDE banner2.html--> <!--#4DENDIF--> <!--#4DLOOP [TABLE]--> (Loop on the current selection) <!--#4DIF ([TABLE]ValNum>10)--> (If [TABLE]ValNum>10) <!--#4DINCLUDE subpage.html--> (Subpage insertion) <!--#4DELSE--> (Else) <B>Value: <!--#4DTEXT [TABLE]ValNum--></B><BR> (Field display) <!--#4DENDIF--> <!--#4DENDLOOP--> (End for) </BODY> </HTML> Parsing the contents of 'template' pages is done in two contexts:
The following table lists the available 4D transformation tags. For more details, see the description of the tags below.
(*)The tags should generally be inserted as HTML comments (<!--#Tag Content-->) in the source text. An alternative syntax using $ is possible under certain conditions for tags returning values, to make them conform to XML. For more information, see Alternative syntax for 4DTEXT, 4DHTML, 4DEVAL below.
Running a 4D method with 4DTEXT, 4DHTML, 4DEVAL, 4DSCRIPT, 4DIF, 4DELSEIF or 4DLOOP from a web request is subject to the “Available via tags and 4D URLs (4DACTION ...)” attribute value defined in the properties of the method. If the attribute is not checked for the method, it can not be called from a web request. For more information on this point, see the Connection Security section. 4D tags are interpreted recursively: 4D always attempts to reinterpret the result of a transformation and, if a new transformation has taken place, an additional interpretation is performed, and so on until the product obtained no longer requires any further transformation. For example, given the following statement: <!--#4DHTML [Mail]Letter_type--> If the [Mail]Letter_type text field itself contains a tag, for example <!--#4DSCRIPT/m_Gender-->, this tag will be evaluated recursively after the interpretation of the 4DHTML tag. This powerful principle meets most needs related to text transformation. Note, however, that in some cases this can also allow malicious code to be inserted. For more information about this point, refer to the following section. 4D transformation tags accept different types of data as parameters: text, variables, methods, command names, etc. When this data is provided by your own code, there is no risk of malicious code insertion since you control the input. However, your database code often works with data that was, at one time or another, introduced through an external source (user input, import, etc.). To ensure the correct evaluation of expressions processed via tags, regardless of the language or 4D version, it's recommended to use the tokenized syntax for elements whose name may vary over versions (commands, tables, fields, constants). For example, to insert the Current time command, enter 'Current time:C178'. For more information on this point, see the Using tokens in formulas section. Starting from v15 R4, 4D always uses the period character (.) as a decimal separator when evaluating a numerical expression using a 4D tag 4DTEXT, 4DVAR, 4DHTML, 4DHTMLVAR, and 4DEVAL (as well as the old 4DVAR and 4DHTMLVAR tags). Regional settings are now ignored. This feature facilitates code maintenance and compatibility between 4D languages and versions. For example, whatever the regional settings: value:=10/4 Compatibility note: If your code, converted from a previous version, evaluates numerical expressions using 4D tags with respect to the regional settings, you'll need to adapt it using the String command:
Syntax: <!--#4DTEXT VarName--> or <!--#4DTEXT 4DExpression--> The tag <!--#4DTEXT VarName--> allows you to insert a reference to the 4D variable or expression returning a value. For example, if you write (in an HTML page): <P>Welcome to <!--#4DTEXT vtSiteName-->!</P> The value of the 4D variable vtSiteName will be inserted in the HTML page when it is sent. This value is inserted as simple text, special HTML characters such as ">" are automatically escaped. You can also insert 4D expressions using the 4DTEXT tag. You can for example directly insert the contents of a field (<!--#4DTEXT [tableName]fieldName-->), an array element (<!--#4DTEXT tabarr{1}-->) or a method returning a value (<!--#4DTEXT mymethod-->). The expression conversion follows the same rules as the variable ones. Moreover, the expression must comply with 4D syntax rules. In case of an evaluation error, the inserted text will appear as “<!--#4DTEXT myvar--> : ## error # error code”. Notes:
Syntax: <!--#4DHTML VarName--> or <!--#4DHTML 4DExpression--> Just like the 4DTEXT tag, this tag lets you assess a variable or 4D expression that returns a value, and insert it as an HTML expression. Unlike the 4DTEXT tag, this tag does not escape HTML special characters (e.g. ">"). For example, here are the processing results of the 4D text variable myvar with the available tags:
In case of an interpretation error, the inserted text will be “<!--#4DHTML myvar--> : ## error # error code”. Note: For security reasons, it is recommended to use the 4DTEXT tag when processing data introduced from outside the application in order to prevent the insertion of malicious code (see the Prevention of malicious code insertion section below). Syntax: <!--#4DEVAL VarName--> or <!--#4DEVAL 4DExpression--> The 4DEVAL tag allows you to assess a variable or a 4D expression. Like the existing 4DHTML tag, 4DEVAL does not escape HTML characters when returning text. However, unlike 4DHTML or 4DTEXT, 4DEVAL allows you to execute any valid 4D statement, including assignments and expressions that do not return any value. For example, you can execute: $input:="<!--#4DEVAL a:=42-->" //assignment In case of an error during interpretation, the text inserted will be in the form: “<!--#4DEVAL expr-->: ## error # error code”. Note: For security reasons, it is recommended to use the 4DTEXT tag when processing data introduced from outside the application, in order to prevent the insertion of malicious code (see the Prevention of malicious code insertion section below). Syntax: <!--#4DSCRIPT/MethodName/MyParam--> The 4DSCRIPT tag allows you to execute 4D methods when processing the template.. The presence of the <!--#4DSCRIPT/MyMethod/MyParam--> tag as an HTML comment forces the execution of the MyMethod method with the Param parameter as a string in $1. Note: If the tag is called in the context of a Web process, when the page is loaded, 4D calls the On Web Authentication Database Method (if it exists). If it returns True, 4D executes the method. The method must return text in $0. If the string starts with the code character 1, it is considered as HTML (the same principle is true for the 4DHTML tag). For example, let’s say that you insert the following comment “Today is <!--#4DSCRIPT/MYMETH/MYPARAM-->” into a semi-dynamic Web page. When loading the page, 4D calls the On Web Authentication Database Method (if it exists), then calls the MYMETH method and passes the string “/MYPARAM” as the parameter $1. The method returns text in $0 (for example “12/31/14”); the expression “Today is <!--#4DSCRIPT/MYMETH/MYPARAM––>” therefore becomes “Today is 12/31/14”. The MYMETH method is as follows: //MYMETH Note: A method called by 4DSCRIPT must not call interface elements (DIALOG, ALERT, etc.). As 4D executes methods in their order of appearance, it is absolutely possible to call a method that sets the value of many variables that are referenced further in the document, whichever mode you are using. You can insert as many <!--#4DSCRIPT...--> comments as you want in a template. Syntax: <!--#4DINCLUDE Path--> This tag is mainly designed to allow another HTML page (indicated by the path parameter) to be included in an HTML page. By default, only the body of the HTML page that is specified is included, in other words, the contents found within the <body> and </body> tags (the tags themselves are not included). This lets you avoid conflicts related to meta tags present in the headers. However, if the HTML page specified does not contain <body></body> tags, the entire page is included. It is up to you to verify the consistency of the meta tags. An included page with the <!--#4DINCLUDE --> comment is loaded in the Web server cache the same way as pages called via a URL or sent with the WEB SEND FILE command. In path, put the path leading to the document to include. Warning: In the case of a 4DINCLUDE call, the path is relative to the document being analyzed, that is, the “parent” document. Use the slash character (/) as a folder separator and the two dots (..) to go up one level (HTML syntax). Notes:
The number of <!--#4DINCLUDE path--> within a page is unlimited. However, the <!--#4DINCLUDE path--> calls can be made only at one level. This means that, for example, you cannot insert <!--#4DINCLUDE mydoc3.html--> in the mydoc2.html body page, which is called by <!--#4DINCLUDE mydoc2--> inserted in mydoc1.html. In case of error, the inserted text is "<!--#4DINCLUDE path--> :The document cannot be opened". Examples <!--#4DINCLUDE subpage.html--> <!--#4DINCLUDE folder/subpage.html--> <!--#4DINCLUDE ../folder/subpage.html--> Syntax: <!--#4DBASE folderPath--> The <!--#4DBASE --> tag designates a working directory that is used by the <!--#4DINCLUDE--> tag. The folderPath parameter must contain a pathname relative to the current page and it must end with a slash (/). The designated folder must be located inside the Web folder. Thus the following code (4D v12), which must specify a relative path for each call: <!--#4DINCLUDE subpage.html--> <!--#4DINCLUDE folder/subpage1.html--> <!--#4DINCLUDE folder/subpage2.html--> <!--#4DINCLUDE folder/subpage3.html--> <!--#4DINCLUDE ../folder/subpage.html--> ... can be rewritten using the <!--#4DBASE --> tag: <!--#4DINCLUDE subpage.html--> <!--#4DBASE folder/--> <!--#4DINCLUDE subpage1.html--> <!--#4DINCLUDE subpage2.html--> <!--#4DINCLUDE subpage3.html--> <!--#4DBASE ../folder/--> <!--#4DINCLUDE subpage.html--> <!--#4DBASE WEBFOLDER--> Setting a directory for the home page using the <!--#4DBASE --> tag: /* Index.html */ <!--#4DIF LangFR=True--> <!--#4DBASE FR/--> <!--#4DELSE--> <!--#4DBASE US/--> <!--#4DENDIF--> <!--#4DINCLUDE head.html--> <!--#4DINCLUDE body.html--> <!--#4DINCLUDE footer.html--> In the head.html file, the current folder is modified through <!--#4DBASE -->, without this changing its value in Index.html: /* Head.htm */ /* the working directory here is relative to the included file (FR/ or US/) */ <!--#4DBASE Styles/--> <!--#4DINCLUDE main.css--> <!--#4DINCLUDE product.css--> <!--#4DBASE Scripts/--> <!--#4DINCLUDE main.js--> <!--#4DINCLUDE product.js--> The 4DCODE tag allows you to insert a multi-line 4D code block in a template. When a "<!--#4DCODE" sequence is detected that is followed by a space, a CR or a LF character, 4D interprets all the lines of code up to the next "-->" sequence. The code block itself can contain carriage returns, line feeds, or both; it will be interpreted sequentially by 4D. For example, using the 4DCODE tag, you can write in a template: <!--#4DCODE Note: In a 4DCODE tag, the 4D code must always be written using the English-US language. Therefore, 4DCODE ignores the "Use regional system settings" user preferences for the 4D language (see Language for commands and constants). Here are the 4DCODE tag features:
Note about security: The fact that 4DCODE tags can call any of the 4D language commands or project methods could be seen as a security issue, especially when the database is available through HTTP. However, since it executes server-side code called from your own template files, the tag itself does not represent a security issue. In this context, as for any Web server, security is mainly handled at the level of remote accesses to server files. Syntax: <!--#4DIF expression--> {<!--#4DELSEIF expression2-->...<!--#4DELSEIF expressionN-->} {<!--#4DELSE-->} <!--#4DENDIF--> The expression parameter can contain any valid 4D expression returning a Boolean value. It must be indicated within parenthesis and comply with the 4D syntax rules. The <!--#4DIF expression--> ... <!--#4DENDIF--> blocks can be nested in several levels. Like in 4D, each <!--#4DIF expression--> should match a <!--#4DENDIF-->. In case of an interpretation error, the text “<!--#4DIF expression-->: A Boolean expression was expected” is inserted instead of the contents located between <!--#4DIF --> and <!--#4DENDIF-->. Likewise, if there are not as many <!--#4DENDIF--> as <!--#4DIF -->, the text “<!--#4DIF expression-->: 4DENDIF expected” is inserted instead of the contents located between <!--#4DIF --> and <!--#4DENDIF-->. Using the <!--#4DELSEIF--> tag, you can test an unlimited number of conditions. Only the code that follows the first condition evaluated as True is executed. If no conditions are true, no statement is executed (if there is no final <!--#4DELSE-->). The two following codes are equivalent.
This example of code inserted in a static HTML page displays a different label according the vname#"" expression result: <BODY> ... <!--#4DIF (vname#"")--> Names starting with <!--#4DTEXT vname-->. <!--#4DELSE--> No name has been found. <!--#4DENDIF--> ... </BODY> This example inserts different pages depending on which user is connected: <!--#4DIF LoggedIn=False--> <!--#4DINCLUDE Login.htm --> <!--#4DELSEIF User="Admin" --> <!--#4DINCLUDE AdminPanel.htm --> <!--#4DELSEIF User="Manager" --> <!--#4DINCLUDE SalesDashboard.htm --> <!--#4DELSE--> <!--#4DINCLUDE ItemList.htm --> <!--#4DENDIF--> Syntax: <!--#4DLOOP condition--> <!--#4DENDLOOP--> The <!--#4DLOOP condition--> ... <!--#4DENDLOOP--> blocks can be nested. Like in 4D, each <!--#4DLOOP condition--> should match a <!--#4DENDLOOP-->. There are five kinds of conditions:
In case of an interpretation error, the text “<!--#4DLOOP expression-->: description” is inserted instead of the contents located between <!--#4DLOOP --> and <!--#4DENDLOOP-->. The following messages can be displayed:
Several existing 4D transformation tags can be expressed using a $-based syntax: This alternative syntax is available only for tags used to return processed values:
(Other tags, such as 4DIF or 4DSCRIPT, must be written with the regular syntax). For example, you can write: $4DEVAL(UserName) instead of: <!--#4DEVAL(UserName)--> The main advantage of this syntax is that it allows you to write XML-compliant templates. Some 4D developers need to create and validate XML-based templates using standard XML parser tools. Since the "<" character is invalid in an XML attribute value, it was not possible to use the "<!-- -->" syntax of 4D tags without breaking the document syntax. On the other hand, escaping the "<" character will prevent 4D from interpreting the tags correctly. For example, the following code would cause an XML parsing error because of the first "<" character in the attribute value: <line x1="<!--#4DEVAL $x-->" y1="<!--#4DEVAL $graphY1-->"/> Using the $ syntax, the following code is validated by the parser: <line x1="" y1=""/> Note that $4dtag and <--#4dtag --> are not strictly equivalent: unlike <--#4dtag -->, $4dtag processing does not interpret 4D tags recursively. $ tags are always evaluated once and the result is considered as plain text. Note: For more information on recursive processing, please refer to the paragraph. The reason for this difference is to prevent malicious code injection. As explained below, it is strongly recommended to use 4DTEXT tags instead of 4DHTML tags when handling user text to protect against unwanted reinterpretation of tags: with 4DTEXT, special characters such as "<" are escaped, thus any 4D tags using the <!--#4dtag expression --> syntax will lose their particular meaning. However, since 4DTEXT does not escape the $ symbol, we decided to break support for recursion in order to prevent malicious injection using the $4dtag (expression) syntax. The following examples show the result of processing depending on the syntax and tag used: // example 1 // example 2 // example 3 Note that the $4dtag syntax supports matching pairs of enclosed quotes or parenthesis. For example, suppose that you need to evaluate the following complex (unrealistic) string: String(1) + "\"(hello)\"" You can write: input:="$4DEVAL( String(1)+\"\\\"(hello)\\\"\")"
|
|
|||||||||||||||||||||||||||||||||||||||||||||||||||||||||||