1 /*
2 * Copyright (c) 2002-2025, City of Paris
3 * All rights reserved.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
7 * are met:
8 *
9 * 1. Redistributions of source code must retain the above copyright notice
10 * and the following disclaimer.
11 *
12 * 2. Redistributions in binary form must reproduce the above copyright notice
13 * and the following disclaimer in the documentation and/or other materials
14 * provided with the distribution.
15 *
16 * 3. Neither the name of 'Mairie de Paris' nor 'Lutece' nor the names of its
17 * contributors may be used to endorse or promote products derived from
18 * this software without specific prior written permission.
19 *
20 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
21 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
22 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
23 * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDERS OR CONTRIBUTORS BE
24 * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
25 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
26 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
27 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
28 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
29 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
30 * POSSIBILITY OF SUCH DAMAGE.
31 *
32 * License 1.0
33 */
34 package fr.paris.lutece.portal.service.template;
35
36 import fr.paris.lutece.portal.service.datastore.DatastoreService;
37 import fr.paris.lutece.portal.service.i18n.I18nService;
38 import fr.paris.lutece.portal.service.i18n.I18nTemplateMethod;
39 import fr.paris.lutece.portal.service.plugin.Plugin;
40 import fr.paris.lutece.portal.service.plugin.PluginService;
41 import fr.paris.lutece.portal.service.util.AppLogService;
42 import fr.paris.lutece.util.html.HtmlTemplate;
43
44 import java.util.Locale;
45 import java.util.Map;
46
47 /**
48 * This Service is used to retreive HTML templates, stored as files in the WEB-INF/templates directory of the webapp, to build the user interface. It provides a
49 * cache feature to prevent from loading file each time it is asked.
50 */
51 public final class AppTemplateService
52 {
53 // Variables
54 private static String _strTemplateDefaultPath;
55 private static IFreeMarkerTemplateService _freeMarkerTemplateService;
56
57 /**
58 * Protected constructor
59 */
60 private AppTemplateService( )
61 {
62 }
63
64 /**
65 * Initializes the service with the templates's path
66 *
67 * @param strTemplatePath
68 * The template path
69 */
70 public static void init( String strTemplatePath )
71 {
72 _strTemplateDefaultPath = strTemplatePath;
73 getFreeMarkerTemplateService( ).setSharedVariable( "i18n", new I18nTemplateMethod( ) );
74 }
75
76 /**
77 * Initializes auto-includes and auto-imports for plugins.
78 */
79 public static void initMacros( )
80 {
81 // register core (commons declared in core.xml)
82 Plugin corePlugin = PluginService.getCore( );
83 addPluginAutoIncludes( corePlugin );
84 addPluginAutoImports( corePlugin );
85
86 // register plugins
87 for ( Plugin plugin : PluginService.getPluginList( ) )
88 {
89 addPluginAutoIncludes( plugin );
90 addPluginAutoImports( plugin );
91 }
92
93 // activate current commons stored in the datastore
94 CommonsService.activateCommons( CommonsService.getCurrentCommonsKey( ) );
95 }
96
97 /**
98 * Adds the plugin auto-includes.
99 *
100 * @param plugin
101 * the plugin
102 */
103 private static void addPluginAutoIncludes( Plugin plugin )
104 {
105 for ( String strFileName : plugin.getFreeMarkerAutoIncludes( ) )
106 {
107 AppLogService.info( "New freemarker autoinclude : {} from {}", strFileName, plugin.getName( ) );
108 getFreeMarkerTemplateService( ).addPluginAutoInclude( strFileName );
109 }
110 }
111
112 /**
113 * Adds the plugin auto-imports.
114 *
115 * @param plugin
116 * the plugin
117 */
118 private static void addPluginAutoImports( Plugin plugin )
119 {
120 for ( Map.Entry<String, String> importEntry : plugin.getFreeMarkerAutoImports( ).entrySet( ) )
121 {
122 AppLogService.info( "New freemarker autoimport : {} as {} from {}", importEntry.getValue( ), importEntry.getKey( ), plugin.getName( ) );
123 getFreeMarkerTemplateService( ).addPluginAutoImport( importEntry.getKey( ), importEntry.getValue( ) );
124 }
125 }
126
127 /**
128 * Reset the cache
129 */
130 public static void resetCache( )
131 {
132 getFreeMarkerTemplateService( ).resetCache( );
133 }
134
135 /**
136 * Resets the configuration cache
137 */
138 public static void resetConfiguration( )
139 {
140 getFreeMarkerTemplateService( ).resetConfiguration( );
141 }
142
143 /**
144 * Returns a reference on a template object (load the template or get it from the cache if present.)
145 *
146 * @param strTemplate
147 * The name of the template
148 * @return The template object.
149 */
150 public static HtmlTemplate getTemplate( String strTemplate )
151 {
152 return getTemplate( strTemplate, _strTemplateDefaultPath );
153 }
154
155 /**
156 * Returns a reference on a template object (load the template or get it from the cache if present.)
157 *
158 * @param strTemplate
159 * The name of the template
160 * @param strPath
161 * The specific path to load the template
162 * @return The template object.
163 * @since 1.3.1
164 */
165 public static HtmlTemplate getTemplate( String strTemplate, String strPath )
166 {
167 return getTemplate( strTemplate, strPath, null, null );
168 }
169
170 // //////////////////////////////////////////////////////////////////////////
171 // v1.5
172
173 /**
174 * Returns a reference on a template object (load the template or get it from the cache if present.)
175 *
176 * @param strTemplate
177 * The name of the template
178 * @param locale
179 * The current locale to localize the template
180 * @return The template object.
181 * @since 1.5
182 */
183 public static HtmlTemplate getTemplate( String strTemplate, Locale locale )
184 {
185 return getTemplate( strTemplate, _strTemplateDefaultPath, locale, null );
186 }
187
188 /**
189 * Returns a reference on a template object (load the template or get it from the cache if present.)
190 *
191 * @param strTemplate
192 * The name of the template
193 * @param locale
194 * The current locale to localize the template
195 * @param model
196 * the model to use for loading
197 * @return The template object.
198 * @since 1.5
199 */
200 public static HtmlTemplate getTemplate( String strTemplate, Locale locale, Object model )
201 {
202 HtmlTemplate template;
203
204 // Load the template from the file
205 template = getTemplate( strTemplate, _strTemplateDefaultPath, locale, model );
206
207 return template;
208 }
209
210 /**
211 * Returns a reference on a template object (load the template or get it from the cache if present.)
212 *
213 * @param strTemplate
214 * The name of the template
215 * @param strPath
216 * The specific path to load the template
217 * @param locale
218 * The current locale to localize the template
219 * @param model
220 * the model to use for loading
221 * @return The template object.
222 * @since 1.5
223 */
224 public static HtmlTemplate getTemplate( String strTemplate, String strPath, Locale locale, Object model )
225 {
226 HtmlTemplate template;
227
228 // Load the template from the file
229 template = loadTemplate( strPath, strTemplate, locale, model );
230
231 return template;
232 }
233
234 /**
235 * Returns a reference on a template object using the template data passed in parameter or getting from cache if present
236 *
237 *
238 * @param strFreemarkerTemplateData
239 * The content of the template
240 * @param locale
241 * The current {@link Locale} to localize the template
242 * @param model
243 * The model
244 * @return The template object
245 * @since 1.5
246 */
247 public static HtmlTemplate getTemplateFromStringFtl( String strFreemarkerTemplateData, Locale locale, Object model )
248 {
249 HtmlTemplate template = getFreeMarkerTemplateService( ).loadTemplateFromStringFtl( strFreemarkerTemplateData, locale, model );
250
251 if ( locale != null )
252 {
253 String strLocalized = I18nService.localize( template.getHtml( ), locale );
254 template = new HtmlTemplate( strLocalized );
255 }
256 return template;
257 }
258
259
260 /**
261 * Returns a reference on a template object using the template data passed in parameter or getting from cache if present
262 *
263 * @param strFreemarkerTemplateName The name of the template ( Must be a Fully qualified name for example skin.plugins.myplugin.manage_my_objects )
264 * @param strFreemarkerTemplateData
265 * The content of the template
266 * @param locale
267 * The current {@link Locale} to localize the template
268 * @param model
269 * The model
270 * @param bResetCache true if the template stored in cache must be updated by the content of the strFreemarkerTemplateDa
271 * @return The template object
272 * @since 7.0.5
273 */
274 public static HtmlTemplate getTemplateFromStringFtl( String strFreemarkerTemplateName,String strFreemarkerTemplateData, Locale locale, Object model,boolean bResetCache )
275 {
276 HtmlTemplate template = getFreeMarkerTemplateService( ).loadTemplateFromStringFtl( strFreemarkerTemplateName,strFreemarkerTemplateData, locale, model,bResetCache );
277
278 if ( locale != null )
279 {
280 String strLocalized = I18nService.localize( template.getHtml( ), locale );
281 template = new HtmlTemplate( strLocalized );
282 }
283 return template;
284 }
285
286 /**
287 * Load the template from the file
288 *
289 * @param strTemplate
290 * The name of the template
291 * @param strPath
292 * The specific path to load the template
293 * @param locale
294 * The current locale to localize the template
295 * @param model
296 * the model to use for loading
297 * @return The loaded template
298 */
299 private static HtmlTemplate loadTemplate( String strPath, String strTemplate, Locale locale, Object model )
300 {
301 HtmlTemplate template;
302 template = getFreeMarkerTemplateService( ).loadTemplate( strPath, strTemplate, locale, model );
303
304 if ( locale != null )
305 {
306 String strLocalized = I18nService.localize( template.getHtml( ), locale );
307 template = new HtmlTemplate( strLocalized );
308 }
309
310 template = new HtmlTemplate( DatastoreService.replaceKeys( template.getHtml( ) ) );
311
312 return template;
313 }
314
315 /**
316 * Get the instance of free marker template service
317 *
318 * @return the instance of free marker template service
319 */
320 private static IFreeMarkerTemplateService getFreeMarkerTemplateService( )
321 {
322 if ( _freeMarkerTemplateService == null )
323 {
324 _freeMarkerTemplateService = FreeMarkerTemplateService.getInstance( );
325 _freeMarkerTemplateService.init( _strTemplateDefaultPath );
326 }
327
328 return _freeMarkerTemplateService;
329 }
330 }