blob: e8ecee57f0fdefa175c8bcc8d05422c1aba72448 [file] [log] [blame]
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8"/>
<meta name="viewport" content="width=device-width, initial-scale=1.0"/>
<meta name="Date-Revision-yyyymmdd" content="20140918"/>
<meta http-equiv="Content-Language" content="en"/>
<meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1">
<title>Tag Syntax</title>
<link href="//fonts.googleapis.com/css?family=Source+Sans+Pro:300,400,600,700,400italic,600italic,700italic" rel="stylesheet" type="text/css">
<link href="//netdna.bootstrapcdn.com/font-awesome/4.0.3/css/font-awesome.css" rel="stylesheet">
<link href="/css/main.css" rel="stylesheet">
<link href="/css/custom.css" rel="stylesheet">
<link href="/highlighter/github-theme.css" rel="stylesheet">
<script src="//code.jquery.com/jquery-1.11.0.min.js"></script>
<script type="text/javascript" src="/bootstrap/js/bootstrap.js"></script>
<script type="text/javascript" src="/js/community.js"></script>
</head>
<body>
<a href="http://github.com/apache/struts" class="github-ribbon">
<img style="position: absolute; right: 0; border: 0;" src="https://s3.amazonaws.com/github/ribbons/forkme_right_red_aa0000.png" alt="Fork me on GitHub">
</a>
<header>
<nav>
<div role="navigation" class="navbar navbar-default navbar-fixed-top">
<div class="container">
<div class="navbar-header">
<button type="button" data-toggle="collapse" data-target="#struts-menu" class="navbar-toggle">
Menu
<span class="sr-only">Toggle navigation</span>
<span class="icon-bar"></span>
<span class="icon-bar"></span>
<span class="icon-bar"></span>
</button>
<a href="/index.html" class="navbar-brand logo"><img src="/img/struts-logo.svg"></a>
</div>
<div id="struts-menu" class="navbar-collapse collapse">
<ul class="nav navbar-nav">
<li class="dropdown">
<a data-toggle="dropdown" href="#" class="dropdown-toggle">
Home<b class="caret"></b>
</a>
<ul class="dropdown-menu">
<li><a href="/index.html">Welcome</a></li>
<li><a href="/download.cgi">Download</a></li>
<li><a href="/releases.html">Releases</a></li>
<li><a href="/announce.html">Announcements</a></li>
<li><a href="http://www.apache.org/licenses/">License</a></li>
<li><a href="https://www.apache.org/foundation/thanks.html">Thanks!</a></li>
<li><a href="https://www.apache.org/foundation/sponsorship.html">Sponsorship</a></li>
</ul>
</li>
<li class="dropdown">
<a data-toggle="dropdown" href="#" class="dropdown-toggle">
Support<b class="caret"></b>
</a>
<ul class="dropdown-menu">
<li><a href="/mail.html">User Mailing List</a></li>
<li><a href="https://issues.apache.org/jira/browse/WW">Issue Tracker</a></li>
<li><a href="/security.html">Reporting Security Issues</a></li>
<li class="divider"></li>
<li><a href="https://cwiki.apache.org/confluence/display/WW/Migration+Guide">Version Notes</a></li>
<li><a href="https://cwiki.apache.org/confluence/display/WW/Security+Bulletins">Security Bulletins</a></li>
<li class="divider"></li>
<li><a href="/maven/project-info.html">Maven Project Info</a></li>
<li><a href="/maven/struts2-core/dependencies.html">Struts Core Dependencies</a></li>
<li><a href="/maven/struts2-plugins/modules.html">Plugin Dependencies</a></li>
</ul>
</li>
<li class="dropdown">
<a data-toggle="dropdown" href="#" class="dropdown-toggle">
Documentation<b class="caret"></b>
</a>
<ul class="dropdown-menu">
<li><a href="/birdseye.html">Birds Eye</a></li>
<li><a href="/primer.html">Key Technologies</a></li>
<li><a href="/kickstart.html">Kickstart FAQ</a></li>
<li><a href="https://cwiki.apache.org/confluence/display/WW/Home">Wiki</a></li>
<li class="divider"></li>
<li><a href="/getting-started/">Getting Started</a></li>
<li><a href="/security/">Security Guide</a></li>
<li><a href="/core-developers/">Core Developers Guide</a></li>
<li><a href="/tag-developers/">Tag Developers Guide</a></li>
<li><a href="/maven-archetypes/">Maven Archetypes</a></li>
<li><a href="/plugins/">Plugins</a></li>
<li><a href="/maven/struts2-core/apidocs/index.html">Struts Core API</a></li>
<li><a href="/tag-developers/tag-reference.html">Tag reference</a></li>
<li><a href="https://cwiki.apache.org/confluence/display/WW/FAQs">FAQs</a></li>
<li><a href="http://cwiki.apache.org/S2PLUGINS/home.html">Plugin registry</a></li>
</ul>
</li>
<li class="dropdown">
<a data-toggle="dropdown" href="#" class="dropdown-toggle">
Contributing<b class="caret"></b>
</a>
<ul class="dropdown-menu">
<li><a href="/youatstruts.html">You at Struts</a></li>
<li><a href="/helping.html">How to Help FAQ</a></li>
<li><a href="/dev-mail.html">Development Lists</a></li>
<li><a href="/contributors/">Contributors Guide</a></li>
<li class="divider"></li>
<li><a href="/submitting-patches.html">Submitting patches</a></li>
<li><a href="/builds.html">Source Code and Builds</a></li>
<li><a href="/coding-standards.html">Coding standards</a></li>
<li><a href="https://cwiki.apache.org/confluence/display/WW/Contributors+Guide">Contributors Guide</a></li>
<li class="divider"></li>
<li><a href="/release-guidelines.html">Release Guidelines</a></li>
<li><a href="/bylaws.html">PMC Charter</a></li>
<li><a href="/volunteers.html">Volunteers</a></li>
<li><a href="https://gitbox.apache.org/repos/asf?p=struts.git">Source Repository</a></li>
<li><a href="/updating-website.html">Updating the website</a></li>
</ul>
</li>
<li class="apache"><a href="http://www.apache.org/"><img src="/img/apache.png"></a></li>
</ul>
</div>
</div>
</div>
</nav>
</header>
<article class="container">
<section class="col-md-12">
<a class="edit-on-gh" href="https://github.com/apache/struts-site/edit/master/source/tag-developers/tag-syntax.md" title="Edit this page on GitHub">Edit on GitHub</a>
<a href="index" title="back to Tag Developers Guide"><< back to Tag Developers Guide</a>
<h1 class="no_toc" id="tag-syntax">Tag Syntax</h1>
<ul id="markdown-toc">
<li><a href="#creating-a-dynamic-input-field" id="markdown-toc-creating-a-dynamic-input-field">Creating a dynamic input field</a> <ul>
<li><a href="#using-an-expression-to-set-the-label" id="markdown-toc-using-an-expression-to-set-the-label">Using an expression to set the label</a></li>
</ul>
</li>
<li><a href="#non-string-attributes" id="markdown-toc-non-string-attributes">Non-String Attributes</a> <ul>
<li><a href="#evaluating-booleans" id="markdown-toc-evaluating-booleans">Evaluating booleans</a></li>
<li><a href="#evaluating-booleans-verbose" id="markdown-toc-evaluating-booleans-verbose">Evaluating booleans (verbose)</a></li>
<li><a href="#evaluating-booleans-with-property" id="markdown-toc-evaluating-booleans-with-property">Evaluating booleans (with property)</a></li>
<li><a href="#evaluating-booleans-verbose-with-property" id="markdown-toc-evaluating-booleans-verbose-with-property">Evaluating booleans (verbose with property)</a></li>
</ul>
</li>
<li><a href="#value-is-an-object" id="markdown-toc-value-is-an-object">value is an Object!</a></li>
<li><a href="#probably-wrong" id="markdown-toc-probably-wrong">Probably wrong!</a></li>
<li><a href="#passing-a-literal-value-the-right-way" id="markdown-toc-passing-a-literal-value-the-right-way">Passing a literal value the right way</a></li>
<li><a href="#expression-language-notations" id="markdown-toc-expression-language-notations">Expression Language Notations</a></li>
<li><a href="#disallowed-property-names" id="markdown-toc-disallowed-property-names">Disallowed property names</a></li>
</ul>
<p>The tags are designed to display dynamic data. To create a input field that displays the property “postalCode”,
we’d pass the String “postalCode” to the textfield tag.</p>
<h2 id="creating-a-dynamic-input-field">Creating a dynamic input field</h2>
<pre><code class="language-jsp">&lt;s:textfield name="postalCode"/&gt;
</code></pre>
<p>If there is a “postalCode” property on the value stack, its value will be set to the input field. When the field is
submitted back to the framework, the value of the control will be set back to the “postalCode” property.</p>
<p>Sometimes, we want to pass the dynamic data to a tag. For example, we might want to display a label with the input
field, and we might want to obtain the label from the application’s messages resources. Accordingly, the framework will
parse expressions found in the tag attributes, so that we can merge dynamic data into the tag attributes at runtime.
The expression escape sequence is <code class="highlighter-rouge">%{ ... }</code>. Any text embedded in the escape sequence is evalulated as an expression.</p>
<h3 id="using-an-expression-to-set-the-label">Using an expression to set the label</h3>
<pre><code class="language-jsp">&lt;s:textfield key="postalCode.label" name="postalCode"/&gt;
</code></pre>
<p>The expression language (<a href="ognl">OGNL</a>) lets us call methods and evaluate properties. The method <code class="highlighter-rouge">getText</code> is provided
by <code class="highlighter-rouge">ActionSupport</code>, which is the base class for most Actions. Since the Action is on the stack, we can call any of its
methods from an expression, including <code class="highlighter-rouge">getText</code>.</p>
<h2 id="non-string-attributes">Non-String Attributes</h2>
<p>The HTTP protocol is text-based, but some tags have non-String attribute types, like <code class="highlighter-rouge">bool</code> or <code class="highlighter-rouge">int</code>. To make using
non-String attributes intuitative, the framework evaulates <strong>all</strong> non-String attributes as an expression.
In this case, you do not need to use the escape notation. (But, if you do anyway , the framework will just strip it off.)</p>
<h3 id="evaluating-booleans">Evaluating booleans</h3>
<pre><code class="language-jsp">&lt;s:select key="state.label" name="state" multiple="true"/&gt;
</code></pre>
<p>Since the attribute <code class="highlighter-rouge">multiple</code> maps to a boolean property, the framework does not interpret the value as a String.
The value is evaluated as an expression and automtically converted to a boolean.</p>
<p>Since it’s easy to forget which attributes are String and which are non-String, you can still use the escape notation.</p>
<h3 id="evaluating-booleans-verbose">Evaluating booleans (verbose)</h3>
<pre><code class="language-jsp">&lt;s:select key="state.label" name="state" multiple="%{true}"/&gt;
</code></pre>
<h3 id="evaluating-booleans-with-property">Evaluating booleans (with property)</h3>
<pre><code class="language-jsp">&lt;s:select key="state.label" name="state" multiple="allowMultiple"/&gt;
</code></pre>
<h3 id="evaluating-booleans-verbose-with-property">Evaluating booleans (verbose with property)</h3>
<pre><code class="language-jsp">&lt;s:select key="state.label" name="state" multiple="%{allowMultiple}"/&gt;
</code></pre>
<h2 id="value-is-an-object">value is an Object!</h2>
<p>Most often, the <code class="highlighter-rouge">value</code> attribute is set automatically, since <code class="highlighter-rouge">name</code> attribute usually tells the framework which
property to call to set the <code class="highlighter-rouge">value</code>. But, if there is a reason to set the <code class="highlighter-rouge">value</code> directly, be advised that <code class="highlighter-rouge">value</code>
<strong>is an Object <em>NOT</em> a String</strong>.</p>
<blockquote>
<p>NOTE: Since <code class="highlighter-rouge">value</code> is not a String, whatever is passed to <code class="highlighter-rouge">value</code> is evaluated as an expression - <strong>NOT</strong> a String literal.</p>
</blockquote>
<h2 id="probably-wrong">Probably wrong!</h2>
<pre><code class="language-jsp">&lt;s:textfield key="state.label" name="state" value="ca"/&gt;
</code></pre>
<p>If a <code class="highlighter-rouge">textfield</code> is passed the value attribute <code class="highlighter-rouge">ca</code>, the framework will look for a property named <code class="highlighter-rouge">getCa</code>. Generally,
this is not what we mean. What we mean to do is pass a literal String. In the expression language, literals are placed
within quotes</p>
<h2 id="passing-a-literal-value-the-right-way">Passing a literal value the right way</h2>
<pre><code class="language-jsp">&lt;s:textfield key="state.label" name="state" value="%{'ca'}" /&gt;
</code></pre>
<p>Another approach would be to use the idiom <code class="highlighter-rouge">value="'ca'"</code>, but, in this case, using the expression notation is recommended.</p>
<p>Boiled down, the tag attributes are evaluated using three rules.</p>
<ol>
<li>All <em>String</em> attribute types are <em>parsed</em> for the <code class="highlighter-rouge">%{ ... }</code> notation.</li>
<li>All <em>non-String</em> attribute types are <strong>not</strong> parsed, but evaluated directly as an expression</li>
<li>The exception to rule #2 is that if the <em>non-String</em> attribute uses the escape notion <code class="highlighter-rouge">%{}</code>, the notation is ignored
as redundant, and the content evaluated.</li>
</ol>
<p>Please remember about <em>altSyntax</em> option that can change when value is evaluated as an expression - <a href="alt-syntax">Alt Syntax</a></p>
<h2 id="expression-language-notations">Expression Language Notations</h2>
<ul>
<li>A JavaBean object in a standard context in Freemarker, Velocity, or JSTL EL (Not OGNL).
<pre><code class="language-jsp">Username: ${user.username}
</code></pre>
</li>
<li>A username property on the Value Stack.
<pre><code class="language-jsp">&lt;s:textfield name="username"/&gt;
</code></pre>
</li>
<li>Another way to refer to a property placed on the Value Stack.
<pre><code class="language-jsp">&lt;s:url var="es" action="Hello"&gt;
&lt;s:param name="request_locale"&gt;es&lt;/s:param&gt;
&lt;/s:url&gt;
&lt;s:a href="%{es}"&gt;Espanol&lt;/s:a&gt;
</code></pre>
</li>
<li>A static Map, as in <code class="highlighter-rouge">put("username","trillian")</code>.
<pre><code class="language-jsp">&lt;s:property value="#session.user.username" /&gt;
&lt;s:select label="FooBar" name="foo" list="#{'username':'trillian', 'username':'zaphod'}" /&gt;
</code></pre>
</li>
</ul>
<h2 id="disallowed-property-names">Disallowed property names</h2>
<p>The following names of property are disallowed:</p>
<ul>
<li>parameters</li>
<li>application</li>
<li>session</li>
<li>struts</li>
<li>request</li>
<li>servletRequest</li>
<li>servletResponse</li>
</ul>
<p>The below code will not work:</p>
<pre><code class="language-jsp">&lt;s:iterator value="parameters"/&gt;
</code></pre>
<div class="language-java highlighter-rouge"><div class="highlight"><pre class="highlight"><code>
<span class="kd">public</span> <span class="kd">class</span> <span class="nc">MyAction</span> <span class="o">{</span>
<span class="kd">private</span> <span class="n">String</span><span class="o">[]</span> <span class="n">parameters</span><span class="o">;</span>
<span class="kd">public</span> <span class="n">String</span><span class="o">[]</span> <span class="nf">getParameters</span><span class="o">()</span> <span class="o">{</span>
<span class="k">return</span> <span class="n">parameters</span><span class="o">;</span>
<span class="o">}</span>
<span class="o">}</span>
</code></pre></div></div>
</section>
</article>
<footer class="container">
<div class="col-md-12">
Copyright &copy; 2000-2018 <a href="http://www.apache.org/">The Apache Software Foundation </a>.
All Rights Reserved.
</div>
<div class="col-md-12">
Apache Struts, Struts, Apache, the Apache feather logo, and the Apache Struts project logos are
trademarks of The Apache Software Foundation.
</div>
<div class="col-md-12">Logo and website design donated by <a href="https://softwaremill.com/">SoftwareMill</a>.</div>
</footer>
<script>!function (d, s, id) {
var js, fjs = d.getElementsByTagName(s)[0];
if (!d.getElementById(id)) {
js = d.createElement(s);
js.id = id;
js.src = "//platform.twitter.com/widgets.js";
fjs.parentNode.insertBefore(js, fjs);
}
}(document, "script", "twitter-wjs");</script>
<script src="https://apis.google.com/js/platform.js" async="async" defer="defer"></script>
<div id="fb-root"></div>
<script>(function (d, s, id) {
var js, fjs = d.getElementsByTagName(s)[0];
if (d.getElementById(id)) return;
js = d.createElement(s);
js.id = id;
js.src = "//connect.facebook.net/en_GB/all.js#xfbml=1";
fjs.parentNode.insertBefore(js, fjs);
}(document, 'script', 'facebook-jssdk'));</script>
</body>
</html>