001    /**
002     * Copyright (c) 2000-2013 Liferay, Inc. All rights reserved.
003     *
004     * This library is free software; you can redistribute it and/or modify it under
005     * the terms of the GNU Lesser General Public License as published by the Free
006     * Software Foundation; either version 2.1 of the License, or (at your option)
007     * any later version.
008     *
009     * This library is distributed in the hope that it will be useful, but WITHOUT
010     * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
011     * FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
012     * details.
013     */
014    
015    package com.liferay.portal.freemarker;
016    
017    import com.liferay.portal.kernel.freemarker.FreeMarkerContext;
018    import com.liferay.portal.kernel.freemarker.FreeMarkerVariables;
019    import com.liferay.portal.kernel.json.JSONFactoryUtil;
020    import com.liferay.portal.kernel.language.LanguageUtil;
021    import com.liferay.portal.kernel.language.UnicodeLanguageUtil;
022    import com.liferay.portal.kernel.log.Log;
023    import com.liferay.portal.kernel.log.LogFactoryUtil;
024    import com.liferay.portal.kernel.servlet.BrowserSnifferUtil;
025    import com.liferay.portal.kernel.util.ArrayUtil;
026    import com.liferay.portal.kernel.util.ArrayUtil_IW;
027    import com.liferay.portal.kernel.util.DateUtil_IW;
028    import com.liferay.portal.kernel.util.FastDateFormatFactoryUtil;
029    import com.liferay.portal.kernel.util.GetterUtil;
030    import com.liferay.portal.kernel.util.GetterUtil_IW;
031    import com.liferay.portal.kernel.util.HtmlUtil;
032    import com.liferay.portal.kernel.util.HttpUtil;
033    import com.liferay.portal.kernel.util.JavaConstants;
034    import com.liferay.portal.kernel.util.LocaleUtil;
035    import com.liferay.portal.kernel.util.ParamUtil_IW;
036    import com.liferay.portal.kernel.util.PrefsPropsUtil;
037    import com.liferay.portal.kernel.util.PropsUtil;
038    import com.liferay.portal.kernel.util.Randomizer_IW;
039    import com.liferay.portal.kernel.util.StaticFieldGetter;
040    import com.liferay.portal.kernel.util.StringPool;
041    import com.liferay.portal.kernel.util.StringUtil_IW;
042    import com.liferay.portal.kernel.util.TimeZoneUtil_IW;
043    import com.liferay.portal.kernel.util.UnicodeFormatter_IW;
044    import com.liferay.portal.kernel.util.Validator;
045    import com.liferay.portal.kernel.util.Validator_IW;
046    import com.liferay.portal.kernel.xml.SAXReader;
047    import com.liferay.portal.model.Layout;
048    import com.liferay.portal.model.Theme;
049    import com.liferay.portal.service.permission.AccountPermissionUtil;
050    import com.liferay.portal.service.permission.CommonPermissionUtil;
051    import com.liferay.portal.service.permission.GroupPermissionUtil;
052    import com.liferay.portal.service.permission.LayoutPermissionUtil;
053    import com.liferay.portal.service.permission.OrganizationPermissionUtil;
054    import com.liferay.portal.service.permission.PasswordPolicyPermissionUtil;
055    import com.liferay.portal.service.permission.PortalPermissionUtil;
056    import com.liferay.portal.service.permission.PortletPermissionUtil;
057    import com.liferay.portal.service.permission.RolePermissionUtil;
058    import com.liferay.portal.service.permission.UserGroupPermissionUtil;
059    import com.liferay.portal.service.permission.UserPermissionUtil;
060    import com.liferay.portal.theme.NavItem;
061    import com.liferay.portal.theme.RequestVars;
062    import com.liferay.portal.theme.ThemeDisplay;
063    import com.liferay.portal.util.PortalUtil;
064    import com.liferay.portal.util.SessionClicks_IW;
065    import com.liferay.portal.util.WebKeys;
066    import com.liferay.portal.velocity.ServiceLocator;
067    import com.liferay.portal.velocity.UtilLocator;
068    import com.liferay.portal.velocity.VelocityPortletPreferences;
069    import com.liferay.portal.webserver.WebServerServletTokenUtil;
070    import com.liferay.portlet.PortletURLFactoryUtil;
071    import com.liferay.portlet.expando.service.ExpandoColumnLocalService;
072    import com.liferay.portlet.expando.service.ExpandoRowLocalService;
073    import com.liferay.portlet.expando.service.ExpandoTableLocalService;
074    import com.liferay.portlet.expando.service.ExpandoValueLocalService;
075    import com.liferay.portlet.journalcontent.util.JournalContentUtil;
076    import com.liferay.taglib.util.VelocityTaglibImpl;
077    import com.liferay.util.portlet.PortletRequestUtil;
078    
079    import freemarker.ext.beans.BeansWrapper;
080    
081    import java.lang.reflect.Method;
082    
083    import java.util.List;
084    import java.util.Map;
085    
086    import javax.portlet.PortletConfig;
087    import javax.portlet.PortletRequest;
088    import javax.portlet.PortletResponse;
089    import javax.portlet.RenderRequest;
090    import javax.portlet.RenderResponse;
091    
092    import javax.servlet.http.HttpServletRequest;
093    
094    import org.apache.struts.taglib.tiles.ComponentConstants;
095    import org.apache.struts.tiles.ComponentContext;
096    
097    /**
098     * @author Mika Koivisto
099     * @author Raymond Aug??
100     */
101    public class FreeMarkerVariablesImpl implements FreeMarkerVariables {
102    
103            @Override
104            public void insertHelperUtilities(
105                    FreeMarkerContext freeMarkerContext, String[] restrictedVariables) {
106    
107                    // Array util
108    
109                    freeMarkerContext.put("arrayUtil", ArrayUtil_IW.getInstance());
110    
111                    // Browser sniffer
112    
113                    try {
114                            freeMarkerContext.put(
115                                    "browserSniffer", BrowserSnifferUtil.getBrowserSniffer());
116                    }
117                    catch (SecurityException se) {
118                            _log.error(se, se);
119                    }
120    
121                    // Date format
122    
123                    try {
124                            freeMarkerContext.put(
125                                    "dateFormatFactory",
126                                    FastDateFormatFactoryUtil.getFastDateFormatFactory());
127                    }
128                    catch (SecurityException se) {
129                            _log.error(se, se);
130                    }
131    
132                    // Date util
133    
134                    freeMarkerContext.put("dateUtil", DateUtil_IW.getInstance());
135    
136                    // Enum util
137    
138                    freeMarkerContext.put(
139                            "enumUtil", BeansWrapper.getDefaultInstance().getEnumModels());
140    
141                    try {
142    
143                            // Service locator
144    
145                            ServiceLocator serviceLocator = ServiceLocator.getInstance();
146    
147                            insertHelperUtility(
148                                    freeMarkerContext, restrictedVariables, "serviceLocator",
149                                    serviceLocator);
150    
151                            // Expando column service
152    
153                            try {
154                                    freeMarkerContext.put(
155                                            "expandoColumnLocalService",
156                                            serviceLocator.findService(
157                                                    ExpandoColumnLocalService.class.getName()));
158                            }
159                            catch (SecurityException se) {
160                                    _log.error(se, se);
161                            }
162    
163                            // Expando row service
164    
165                            try {
166                                    freeMarkerContext.put(
167                                            "expandoRowLocalService",
168                                            serviceLocator.findService(
169                                                    ExpandoRowLocalService.class.getName()));
170                            }
171                            catch (SecurityException se) {
172                                    _log.error(se, se);
173                            }
174    
175                            // Expando table service
176    
177                            try {
178                                    freeMarkerContext.put(
179                                            "expandoTableLocalService",
180                                            serviceLocator.findService(
181                                                    ExpandoTableLocalService.class.getName()));
182                            }
183                            catch (SecurityException se) {
184                                    _log.error(se, se);
185                            }
186    
187                            // Expando value service
188    
189                            try {
190                                    freeMarkerContext.put(
191                                            "expandoValueLocalService",
192                                            serviceLocator.findService(
193                                                    ExpandoValueLocalService.class.getName()));
194                            }
195                            catch (SecurityException se) {
196                                    _log.error(se, se);
197                            }
198                    }
199                    catch (SecurityException se) {
200                            _log.error(se, se);
201                    }
202    
203                    // Getter util
204    
205                    freeMarkerContext.put("getterUtil", GetterUtil_IW.getInstance());
206    
207                    // Html util
208    
209                    try {
210                            freeMarkerContext.put("htmlUtil", HtmlUtil.getHtml());
211                    }
212                    catch (SecurityException se) {
213                            _log.error(se, se);
214                    }
215    
216                    // Http util
217    
218                    try {
219                            freeMarkerContext.put("httpUtil", HttpUtil.getHttp());
220                    }
221                    catch (SecurityException se) {
222                            _log.error(se, se);
223                    }
224    
225                    // Journal content util
226    
227                    try {
228                            freeMarkerContext.put(
229                                    "journalContentUtil", JournalContentUtil.getJournalContent());
230                    }
231                    catch (SecurityException se) {
232                            _log.error(se, se);
233                    }
234    
235                    // JSON factory util
236    
237                    try {
238                            freeMarkerContext.put(
239                                    "jsonFactoryUtil", JSONFactoryUtil.getJSONFactory());
240                    }
241                    catch (SecurityException se) {
242                            _log.error(se, se);
243                    }
244    
245                    // Language util
246    
247                    try {
248                            freeMarkerContext.put("languageUtil", LanguageUtil.getLanguage());
249                    }
250                    catch (SecurityException se) {
251                            _log.error(se, se);
252                    }
253    
254                    try {
255                            freeMarkerContext.put(
256                                    "unicodeLanguageUtil",
257                                    UnicodeLanguageUtil.getUnicodeLanguage());
258                    }
259                    catch (SecurityException se) {
260                            _log.error(se, se);
261                    }
262    
263                    // Locale util
264    
265                    try {
266                            freeMarkerContext.put("localeUtil", LocaleUtil.getInstance());
267                    }
268                    catch (SecurityException se) {
269                            _log.error(se, se);
270                    }
271    
272                    // Object util
273    
274                    freeMarkerContext.put("objectUtil", new LiferayObjectConstructor());
275    
276                    // Param util
277    
278                    freeMarkerContext.put("paramUtil", ParamUtil_IW.getInstance());
279    
280                    // Portal util
281    
282                    try {
283                            insertHelperUtility(
284                                    freeMarkerContext, restrictedVariables, "portalUtil",
285                                    PortalUtil.getPortal());
286                            insertHelperUtility(
287                                    freeMarkerContext, restrictedVariables, "portal",
288                                    PortalUtil.getPortal());
289                    }
290                    catch (SecurityException se) {
291                            _log.error(se, se);
292                    }
293    
294                    // Prefs props util
295    
296                    try {
297                            insertHelperUtility(
298                                    freeMarkerContext, restrictedVariables, "prefsPropsUtil",
299                                    PrefsPropsUtil.getPrefsProps());
300                    }
301                    catch (SecurityException se) {
302                            _log.error(se, se);
303                    }
304    
305                    // Props util
306    
307                    try {
308                            insertHelperUtility(
309                                    freeMarkerContext, restrictedVariables, "propsUtil",
310                                    PropsUtil.getProps());
311                    }
312                    catch (SecurityException se) {
313                            _log.error(se, se);
314                    }
315    
316                    // Portlet URL factory
317    
318                    try {
319                            freeMarkerContext.put(
320                                    "portletURLFactory",
321                                    PortletURLFactoryUtil.getPortletURLFactory());
322                    }
323                    catch (SecurityException se) {
324                            _log.error(se, se);
325                    }
326    
327                    // Portlet preferences
328    
329                    insertHelperUtility(
330                            freeMarkerContext, restrictedVariables,
331                            "freeMarkerPortletPreferences", new VelocityPortletPreferences());
332    
333                    // Randomizer
334    
335                    freeMarkerContext.put(
336                            "randomizer", Randomizer_IW.getInstance().getWrappedInstance());
337    
338                    try {
339    
340                            // Util locator
341    
342                            UtilLocator utilLocator = UtilLocator.getInstance();
343    
344                            insertHelperUtility(
345                                    freeMarkerContext, restrictedVariables, "utilLocator",
346                                    utilLocator);
347    
348                            // SAX reader util
349    
350                            try {
351                                    freeMarkerContext.put(
352                                            "saxReaderUtil",
353                                            utilLocator.findUtil(SAXReader.class.getName()));
354                            }
355                            catch (SecurityException se) {
356                                    _log.error(se, se);
357                            }
358                    }
359                    catch (SecurityException se) {
360                            _log.error(se, se);
361                    }
362    
363                    // Session clicks
364    
365                    try {
366                            insertHelperUtility(
367                                    freeMarkerContext, restrictedVariables, "sessionClicks",
368                                    SessionClicks_IW.getInstance());
369                    }
370                    catch (SecurityException se) {
371                            _log.error(se, se);
372                    }
373    
374                    // Static field getter
375    
376                    freeMarkerContext.put(
377                            "staticFieldGetter", StaticFieldGetter.getInstance());
378    
379                    // Static class util
380    
381                    freeMarkerContext.put(
382                            "staticUtil", BeansWrapper.getDefaultInstance().getStaticModels());
383    
384                    // String util
385    
386                    freeMarkerContext.put("stringUtil", StringUtil_IW.getInstance());
387    
388                    // Time zone util
389    
390                    freeMarkerContext.put("timeZoneUtil", TimeZoneUtil_IW.getInstance());
391    
392                    // Unicode formatter
393    
394                    freeMarkerContext.put(
395                            "unicodeFormatter", UnicodeFormatter_IW.getInstance());
396    
397                    // Validator
398    
399                    freeMarkerContext.put("validator", Validator_IW.getInstance());
400    
401                    // VelocityTaglib methods
402    
403                    try {
404                            Class<?> clazz = VelocityTaglibImpl.class;
405    
406                            Method method = clazz.getMethod(
407                                    "layoutIcon", new Class[] {Layout.class});
408    
409                            freeMarkerContext.put("velocityTaglib#layoutIcon", method);
410                    }
411                    catch (Exception e) {
412                            _log.error(e, e);
413                    }
414    
415                    // Web server servlet token
416    
417                    try {
418                            freeMarkerContext.put(
419                                    "webServerToken",
420                                    WebServerServletTokenUtil.getWebServerServletToken());
421                    }
422                    catch (SecurityException se) {
423                            _log.error(se, se);
424                    }
425    
426                    // Permissions
427    
428                    try {
429                            freeMarkerContext.put(
430                                    "accountPermission",
431                                    AccountPermissionUtil.getAccountPermission());
432                    }
433                    catch (SecurityException se) {
434                            _log.error(se, se);
435                    }
436    
437                    try {
438                            freeMarkerContext.put(
439                                    "commonPermission", CommonPermissionUtil.getCommonPermission());
440                    }
441                    catch (SecurityException se) {
442                            _log.error(se, se);
443                    }
444    
445                    try {
446                            freeMarkerContext.put(
447                                    "groupPermission", GroupPermissionUtil.getGroupPermission());
448                    }
449                    catch (SecurityException se) {
450                            _log.error(se, se);
451                    }
452    
453                    try {
454                            freeMarkerContext.put(
455                                    "layoutPermission", LayoutPermissionUtil.getLayoutPermission());
456                    }
457                    catch (SecurityException se) {
458                            _log.error(se, se);
459                    }
460    
461                    try {
462                            freeMarkerContext.put(
463                                    "organizationPermission",
464                                    OrganizationPermissionUtil.getOrganizationPermission());
465                    }
466                    catch (SecurityException se) {
467                            _log.error(se, se);
468                    }
469    
470                    try {
471                            freeMarkerContext.put(
472                                    "passwordPolicyPermission",
473                                    PasswordPolicyPermissionUtil.getPasswordPolicyPermission());
474                    }
475                    catch (SecurityException se) {
476                            _log.error(se, se);
477                    }
478    
479                    try {
480                            freeMarkerContext.put(
481                                    "portalPermission", PortalPermissionUtil.getPortalPermission());
482                    }
483                    catch (SecurityException se) {
484                            _log.error(se, se);
485                    }
486    
487                    try {
488                            freeMarkerContext.put(
489                                    "portletPermission",
490                                    PortletPermissionUtil.getPortletPermission());
491                    }
492                    catch (SecurityException se) {
493                            _log.error(se, se);
494                    }
495    
496                    try {
497                            freeMarkerContext.put(
498                                    "rolePermission", RolePermissionUtil.getRolePermission());
499                    }
500                    catch (SecurityException se) {
501                            _log.error(se, se);
502                    }
503    
504                    try {
505                            freeMarkerContext.put(
506                                    "userGroupPermission",
507                                    UserGroupPermissionUtil.getUserGroupPermission());
508                    }
509                    catch (SecurityException se) {
510                            _log.error(se, se);
511                    }
512    
513                    try {
514                            freeMarkerContext.put(
515                                    "userPermission", UserPermissionUtil.getUserPermission());
516                    }
517                    catch (SecurityException se) {
518                            _log.error(se, se);
519                    }
520    
521                    // Deprecated
522    
523                    try {
524                            freeMarkerContext.put(
525                                    "imageToken",
526                                    WebServerServletTokenUtil.getWebServerServletToken());
527                    }
528                    catch (SecurityException se) {
529                            _log.error(se, se);
530                    }
531            }
532    
533            @Override
534            public void insertVariables(
535                            FreeMarkerContext freeMarkerContext, HttpServletRequest request)
536                    throws Exception {
537    
538                    // Request
539    
540                    freeMarkerContext.put("request", request);
541    
542                    // Portlet config
543    
544                    PortletConfig portletConfig = (PortletConfig)request.getAttribute(
545                            JavaConstants.JAVAX_PORTLET_CONFIG);
546    
547                    if (portletConfig != null) {
548                            freeMarkerContext.put("portletConfig", portletConfig);
549                    }
550    
551                    // Render request
552    
553                    final PortletRequest portletRequest =
554                            (PortletRequest)request.getAttribute(
555                                    JavaConstants.JAVAX_PORTLET_REQUEST);
556    
557                    if (portletRequest != null) {
558                            if (portletRequest instanceof RenderRequest) {
559                                    freeMarkerContext.put("renderRequest", portletRequest);
560                            }
561                    }
562    
563                    // Render response
564    
565                    final PortletResponse portletResponse =
566                            (PortletResponse)request.getAttribute(
567                                    JavaConstants.JAVAX_PORTLET_RESPONSE);
568    
569                    if (portletResponse != null) {
570                            if (portletResponse instanceof RenderResponse) {
571                                    freeMarkerContext.put("renderResponse", portletResponse);
572                            }
573                    }
574    
575                    // XML request
576    
577                    if ((portletRequest != null) && (portletResponse != null)) {
578                            freeMarkerContext.put(
579                                    "xmlRequest",
580                                    new Object() {
581    
582                                            @Override
583                                            public String toString() {
584                                                    return PortletRequestUtil.toXML(
585                                                            portletRequest, portletResponse);
586                                            }
587    
588                                    }
589                            );
590                    }
591    
592                    // Theme display
593    
594                    ThemeDisplay themeDisplay = (ThemeDisplay)request.getAttribute(
595                            WebKeys.THEME_DISPLAY);
596    
597                    if (themeDisplay != null) {
598                            Theme theme = themeDisplay.getTheme();
599    
600                            Layout layout = themeDisplay.getLayout();
601                            List<Layout> layouts = themeDisplay.getLayouts();
602    
603                            freeMarkerContext.put("themeDisplay", themeDisplay);
604                            freeMarkerContext.put("company", themeDisplay.getCompany());
605                            freeMarkerContext.put("user", themeDisplay.getUser());
606                            freeMarkerContext.put("realUser", themeDisplay.getRealUser());
607                            freeMarkerContext.put("layout", layout);
608                            freeMarkerContext.put("layouts", layouts);
609                            freeMarkerContext.put(
610                                    "plid", String.valueOf(themeDisplay.getPlid()));
611                            freeMarkerContext.put(
612                                    "layoutTypePortlet", themeDisplay.getLayoutTypePortlet());
613                            freeMarkerContext.put(
614                                    "scopeGroupId", new Long(themeDisplay.getScopeGroupId()));
615                            freeMarkerContext.put(
616                                    "permissionChecker", themeDisplay.getPermissionChecker());
617                            freeMarkerContext.put("locale", themeDisplay.getLocale());
618                            freeMarkerContext.put("timeZone", themeDisplay.getTimeZone());
619                            freeMarkerContext.put("theme", theme);
620                            freeMarkerContext.put("colorScheme", themeDisplay.getColorScheme());
621                            freeMarkerContext.put(
622                                    "portletDisplay", themeDisplay.getPortletDisplay());
623    
624                            // Navigation items
625    
626                            if (layout != null) {
627                                    RequestVars requestVars = new RequestVars(
628                                            request, themeDisplay, layout.getAncestorPlid(),
629                                            layout.getAncestorLayoutId(), freeMarkerContext);
630    
631                                    List<NavItem> navItems = NavItem.fromLayouts(
632                                            requestVars, layouts);
633    
634                                    freeMarkerContext.put("navItems", navItems);
635                            }
636    
637                            // Full css and templates path
638    
639                            String servletContextName = GetterUtil.getString(
640                                    theme.getServletContextName());
641    
642                            freeMarkerContext.put(
643                                    "fullCssPath",
644                                    StringPool.SLASH + servletContextName +
645                                            theme.getFreeMarkerTemplateLoader() + theme.getCssPath());
646    
647                            freeMarkerContext.put(
648                                    "fullTemplatesPath",
649                                    StringPool.SLASH + servletContextName +
650                                            theme.getFreeMarkerTemplateLoader() +
651                                                    theme.getTemplatesPath());
652    
653                            // Init
654    
655                            freeMarkerContext.put(
656                                    "init",
657                                    StringPool.SLASH + themeDisplay.getPathContext() +
658                                            FreeMarkerTemplateLoader.SERVLET_SEPARATOR +
659                                                    "/html/themes/_unstyled/templates/init.ftl");
660    
661                            // Deprecated
662    
663                            freeMarkerContext.put(
664                                    "portletGroupId", new Long(themeDisplay.getScopeGroupId()));
665                    }
666    
667                    // Tiles attributes
668    
669                    insertTilesVariables(freeMarkerContext, request);
670    
671                    // Page title and subtitle
672    
673                    if (request.getAttribute(WebKeys.PAGE_TITLE) != null) {
674                            freeMarkerContext.put(
675                                    "pageTitle", request.getAttribute(WebKeys.PAGE_TITLE));
676                    }
677    
678                    if (request.getAttribute(WebKeys.PAGE_SUBTITLE) != null) {
679                            freeMarkerContext.put(
680                                    "pageSubtitle", request.getAttribute(WebKeys.PAGE_SUBTITLE));
681                    }
682    
683                    // Insert custom ftl variables
684    
685                    Map<String, Object> ftlVariables =
686                            (Map<String, Object>)request.getAttribute(WebKeys.FTL_VARIABLES);
687    
688                    if (ftlVariables != null) {
689                            for (Map.Entry<String, Object> entry : ftlVariables.entrySet()) {
690                                    String key = entry.getKey();
691                                    Object value = entry.getValue();
692    
693                                    if (Validator.isNotNull(key)) {
694                                            freeMarkerContext.put(key, value);
695                                    }
696                            }
697                    }
698            }
699    
700            protected void insertHelperUtility(
701                    FreeMarkerContext freeMarkerContext, String[] restrictedVariables,
702                    String key, Object value) {
703    
704                    if (!ArrayUtil.contains(restrictedVariables, key)) {
705                            freeMarkerContext.put(key, value);
706                    }
707            }
708    
709            protected void insertTilesVariables(
710                    FreeMarkerContext freeMarkerContext, HttpServletRequest request) {
711    
712                    ComponentContext componentContext =
713                            (ComponentContext)request.getAttribute(
714                                    ComponentConstants.COMPONENT_CONTEXT);
715    
716                    if (componentContext == null) {
717                            return;
718                    }
719    
720                    ThemeDisplay themeDisplay = (ThemeDisplay)request.getAttribute(
721                            WebKeys.THEME_DISPLAY);
722    
723                    String tilesTitle = (String)componentContext.getAttribute("title");
724    
725                    themeDisplay.setTilesTitle(tilesTitle);
726    
727                    if (tilesTitle != null) {
728                            freeMarkerContext.put("tilesTitle", tilesTitle);
729                    }
730    
731                    String tilesContent = (String)componentContext.getAttribute("content");
732    
733                    themeDisplay.setTilesContent(tilesContent);
734    
735                    if (tilesContent != null) {
736                            freeMarkerContext.put("tilesContent", tilesContent);
737                    }
738    
739                    boolean tilesSelectable = GetterUtil.getBoolean(
740                            (String)componentContext.getAttribute("selectable"));
741    
742                    themeDisplay.setTilesSelectable(tilesSelectable);
743    
744                    freeMarkerContext.put("tilesSelectable", tilesSelectable);
745            }
746    
747            private static Log _log = LogFactoryUtil.getLog(
748                    FreeMarkerVariablesImpl.class);
749    
750    }