~~ $Id$ ~~ ~~ Licensed to the Apache Software Foundation (ASF) under one ~~ or more contributor license agreements. See the NOTICE file ~~ distributed with this work for additional information ~~ regarding copyright ownership. The ASF licenses this file ~~ to you under the Apache License, Version 2.0 (the ~~ "License"); you may not use this file except in compliance ~~ with the License. You may obtain a copy of the License at ~~ ~~ http://www.apache.org/licenses/LICENSE-2.0 ~~ ~~ Unless required by applicable law or agreed to in writing, ~~ software distributed under the License is distributed on an ~~ "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY ~~ KIND, either express or implied. See the License for the ~~ specific language governing permissions and limitations ~~ under the License. ~~ ----------- Expression Language (EL) support ----------- <> Configuration with initialization parameters is deprecated! If you still want to use it, please refer to {{{../../../2.1/framework/tutorial/advanced/el-support.html}2.1 version of this page}}. Expression Language support With Tiles it is possible to use expression languages not only in JSP pages, but also in XML definition files. Currently supported languages are EL (as in javax.el), i.e. the language used in JSP code, {{{http://mvel.codehaus.org/}MVEL}} and {{{http://www.opensymphony.com/ognl/}OGNL}}. * Configuration To enable the use of expression languages, you are encouraged to use the {{{tutorial/configuration.html#Pure_Java_configuration}Pure Java configuration}} by overriding the {{{../../apidocs/org/apache/tiles/factory/BasicTilesContainerFactory.html#createAttributeEvaluatorFactory(org.apache.tiles.TilesApplicationContext, org.apache.tiles.context.TilesRequestContextFactory, org.apache.tiles.locale.LocaleResolver)} createAttributeEvaluatorFactory}} method of BasicTilesContainerFactory. For example: ------------------------------------ @Override protected AttributeEvaluatorFactory createAttributeEvaluatorFactory( TilesApplicationContext applicationContext, TilesRequestContextFactory contextFactory, LocaleResolver resolver) { ELAttributeEvaluator evaluator = new ELAttributeEvaluator(); // the rest of the initialization... BasicAttributeEvaluatorFactory attributeEvaluatorFactory = new BasicAttributeEvaluatorFactory( new DirectAttributeEvaluator()); attributeEvaluatorFactory.registerAttributeEvaluator("EL", evaluator); return attributeEvaluatorFactory; } ------------------------------------ * EL support The EL language is supported since Tiles 2.1. If you are using Servlet 2.5 or above, you can leverage your container EL support. ------------------------------------ @Override protected AttributeEvaluatorFactory createAttributeEvaluatorFactory( TilesApplicationContext applicationContext, TilesRequestContextFactory contextFactory, LocaleResolver resolver) { //... Initialization of the factory. ELAttributeEvaluator evaluator = new ELAttributeEvaluator(); evaluator.setApplicationContext(applicationContext); JspExpressionFactoryFactory efFactory = new JspExpressionFactoryFactory(); efFactory.setApplicationContext(applicationContext); evaluator.setExpressionFactory(efFactory.getExpressionFactory()); ELResolver elResolver = new CompositeELResolver() { { add(new TilesContextELResolver()); add(new TilesContextBeanELResolver()); add(new ArrayELResolver(false)); add(new ListELResolver(false)); add(new MapELResolver(false)); add(new ResourceBundleELResolver()); add(new BeanELResolver(false)); } }; evaluator.setResolver(elResolver); // End of the attribute evaluator factory initialization. } ------------------------------------ ** Configuration under Servlets 2.4/JSP 2.0 If you are using Servlets 2.4/JSP 2.0, you still can use Tiles EL support but: * You have to put <<>> (or newer version) and <<>> in your classpath. * Inject the <<>> from Tomcat into the attribute evaluator, overriding {{{../../apidocs/org/apache/tiles/factory/BasicTilesContainerFactory.html#createAttributeEvaluatorFactory(org.apache.tiles.TilesApplicationContext, org.apache.tiles.context.TilesRequestContextFactory, org.apache.tiles.locale.LocaleResolver)}createAttributeEvaluatorFactory}} of <<>> class this way: ------------------------------------ @Override protected AttributeEvaluatorFactory createAttributeEvaluatorFactory( TilesApplicationContext applicationContext, TilesRequestContextFactory contextFactory, LocaleResolver resolver) { BasicAttributeEvaluatorFactory attributeEvaluatorFactory = new BasicAttributeEvaluatorFactory( createELEvaluator(applicationContext)); return attributeEvaluatorFactory; } /** * Creates the EL evaluator. * * @param applicationContext The Tiles application context. * @return The EL evaluator. */ private ELAttributeEvaluator createELEvaluator( TilesApplicationContext applicationContext) { ELAttributeEvaluator evaluator = new ELAttributeEvaluator(); evaluator.setApplicationContext(applicationContext); // This is the important piece! evaluator.setExpressionFactory(new ExpressionFactoryImpl()); // End of the important piece! ELResolver elResolver = new CompositeELResolver() { { add(new TilesContextELResolver()); add(new TilesContextBeanELResolver()); add(new ArrayELResolver(false)); add(new ListELResolver(false)); add(new MapELResolver(false)); add(new ResourceBundleELResolver()); add(new BeanELResolver(false)); } }; evaluator.setResolver(elResolver); return evaluator; } ------------------------------------ ** Usage Let's use this example: ------------------------------------ ------------------------------------ Before rendering the definition: * The template name will be taken from the "layout" attribute, searched in every scope. * The body will be taken from the "body" attribute in request scope. * {MVEL Support} To use MVEL support you need to register an instance of {{{../../apidocs/org/apache/tiles/mvel/MVELAttributeEvaluator.html} MVELAttributeEvaluator}} along with other supporting objects. ------------------------------------ @Override protected AttributeEvaluatorFactory createAttributeEvaluatorFactory( TilesApplicationContext applicationContext, TilesRequestContextFactory contextFactory, LocaleResolver resolver) { TilesRequestContextHolder requestHolder = new TilesRequestContextHolder(); VariableResolverFactory variableResolverFactory = new TilesContextVariableResolverFactory( requestHolder); variableResolverFactory .setNextFactory(new TilesContextBeanVariableResolverFactory( requestHolder)); MVELAttributeEvaluator evaluator = new MVELAttributeEvaluator(requestHolder, variableResolverFactory); BasicAttributeEvaluatorFactory attributeEvaluatorFactory = new BasicAttributeEvaluatorFactory( new DirectAttributeEvaluator()); attributeEvaluatorFactory.registerAttributeEvaluator("MVEL", evaluator); return attributeEvaluatorFactory; } ------------------------------------ ** Usage Let's use this example: ------------------------------------ ------------------------------------ Before rendering the definition: * The template name will be taken from the "layout" attribute, searched in every scope. * The body will be taken from the "body" attribute in request scope. * {OGNL Support} To use OGNL support you need to register an instance of {{{../../apidocs/org/apache/tiles/ognl/OGNLAttributeEvaluator.html} OGNLAttributeEvaluator}} along with other supporting objects. ------------------------------------ @Override protected AttributeEvaluatorFactory createAttributeEvaluatorFactory( TilesApplicationContext applicationContext, TilesRequestContextFactory contextFactory, LocaleResolver resolver) { try { PropertyAccessor objectPropertyAccessor = OgnlRuntime.getPropertyAccessor(Object.class); PropertyAccessor mapPropertyAccessor = OgnlRuntime.getPropertyAccessor(Map.class); PropertyAccessor applicationContextPropertyAccessor = new NestedObjectDelegatePropertyAccessor( new TilesApplicationContextNestedObjectExtractor(), objectPropertyAccessor); PropertyAccessor requestScopePropertyAccessor = new NestedObjectDelegatePropertyAccessor( new RequestScopeNestedObjectExtractor(), mapPropertyAccessor); PropertyAccessor sessionScopePropertyAccessor = new NestedObjectDelegatePropertyAccessor( new SessionScopeNestedObjectExtractor(), mapPropertyAccessor); PropertyAccessor applicationScopePropertyAccessor = new NestedObjectDelegatePropertyAccessor( new ApplicationScopeNestedObjectExtractor(), mapPropertyAccessor); PropertyAccessorDelegateFactory factory = new TilesContextPropertyAccessorDelegateFactory( objectPropertyAccessor, applicationContextPropertyAccessor, requestScopePropertyAccessor, sessionScopePropertyAccessor, applicationScopePropertyAccessor); PropertyAccessor tilesRequestAccessor = new DelegatePropertyAccessor(factory); OgnlRuntime.setPropertyAccessor(TilesRequestContext.class, tilesRequestAccessor); } catch (OgnlException e) { throw new TilesTestRuntimeException("Cannot initialize OGNL evaluator", e); } BasicAttributeEvaluatorFactory attributeEvaluatorFactory = new BasicAttributeEvaluatorFactory( new DirectAttributeEvaluator()); attributeEvaluatorFactory.registerAttributeEvaluator("MVEL", new OGNLAttributeEvaluator()); return attributeEvaluatorFactory; } ------------------------------------ ** Usage Let's use this example: ------------------------------------ ------------------------------------ Before rendering the definition: * The template name will be taken from the "layout" attribute, searched in every scope. * The body will be taken from the "body" attribute in request scope.