Dynamically Generate a CSS StylesheetPage edited by Chris WewerkaChanges (1)
Full Content1. Implement a class that can turn a TextTemplate into a ResourceReferenceTextTemplateResourceReference.java import org.apache.wicket.IClusterable; import org.apache.wicket.Resource; import org.apache.wicket.ResourceReference; import org.apache.wicket.model.IModel; import org.apache.wicket.util.resource.IResourceStream; import org.apache.wicket.util.resource.StringResourceStream; import org.apache.wicket.util.template.PackagedTextTemplate; import org.apache.wicket.util.template.TextTemplate; import org.apache.wicket.util.time.Time; import java.util.Map; /** * A class which adapts a {...@link PackagedTextTemplate} to a {...@link ResourceReference}. * * @author James Carman */ public class TextTemplateResourceReference extends ResourceReference implements IClusterable { //********************************************************************************************************************** // Fields //********************************************************************************************************************** private static final long serialVersionUID = 1L; private final TextTemplate textTemplate; private final IModel<Map<String,Object>> variablesModel; //********************************************************************************************************************** // Constructors //********************************************************************************************************************** /** * Creates a resource reference to a {...@link PackagedTextTemplate}. * * @param scope the <code>Class</code> to be used for retrieving the classloader for loading the * <code>PackagedTextTemplate</code> * @param fileName the file name * @param variablesModel the template variables as a model */ public TextTemplateResourceReference(final Class<?> scope, final String fileName, IModel<Map<String,Object>> variablesModel) { super(scope, fileName); this.textTemplate = new PackagedTextTemplate(scope, fileName); this.variablesModel = variablesModel; } /** * Creates a resource reference to a {...@link PackagedTextTemplate}. * * @param scope the <code>Class</code> to be used for retrieving the classloader for loading the * <code>PackagedTextTemplate</code> * @param fileName the file name * @param contentType the mime type of this resource, such as "<code>image/jpeg</code>" or "<code>text/html</code>" * @param variablesModel the template variables as a model */ public TextTemplateResourceReference(final Class<?> scope, final String fileName, final String contentType, IModel<Map<String,Object>> variablesModel) { super(scope, fileName); this.textTemplate = new PackagedTextTemplate(scope, fileName, contentType); this.variablesModel = variablesModel; } /** * Creates a resource reference to a {...@link PackagedTextTemplate}. * * @param scope the <code>Class</code> to be used for retrieving the classloader for loading the * <code>PackagedTextTemplate</code> * @param fileName the file name * @param contentType the mime type of this resource, such as "<code>image/jpeg</code>" or "<code>text/html</code>" * @param encoding the file's encoding, for example, "<code>UTF-8</code>" * @param variablesModel the template variables as a model */ public TextTemplateResourceReference(final Class<?> scope, final String fileName, final String contentType, final String encoding, IModel<Map<String,Object>> variablesModel) { super(scope, fileName); this.textTemplate = new PackagedTextTemplate(scope, fileName, contentType, encoding); this.variablesModel = variablesModel; } //********************************************************************************************************************** // Other Methods //********************************************************************************************************************** /** * Creates a new resource which returns the interpolated value of the text template. * @return a new resource which returns the interpolated value of the text template */ protected Resource newResource() { return new Resource() { private static final long serialVersionUID = 1L; public IResourceStream getResourceStream() { final String stringValue = textTemplate.asString(variablesModel.getObject()); variablesModel.detach(); // We're done with the model so detach it! return new StringResourceStream(stringValue, textTemplate.getContentType()); } }; } /** * Returns the last modified time of the {...@link PackagedTextTemplate} itself. * @return the last modified time of the {...@link PackagedTextTemplate} itself */ public Time lastModifiedTime() { return textTemplate.lastModifiedTime(); } } 2. Use the new resource reference class to create a StyleSheetReferenceMyPage.java import org.apache.wicket.markup.html.WebPage; import org.apache.wicket.markup.html.resources.StyleSheetReference; import org.apache.wicket.model.LoadableDetachableModel; import java.util.HashMap; import java.util.Map; /** * @author James Carman */ public class MyPage extends WebPage { public MyPage() { add(new StyleSheetReference("stylesheet", new TextTemplateResourceReference(MyPage.class, "style.css", "text/css", new LoadableDetachableModel<Map<String,Object>>() { private static final long serialVersionUID = 1L; public Map<String,Object> load() { final Map<String,Object> vars = new HashMap<String,Object>(); vars.put("color1", "#0000ff"); return vars; } }))); } } 3. Include the stylesheet link in your markupMyPage.html <html xmlns:wicket="http://wicket.apache.org"> <wicket:head> <link wicket:id="stylesheet"/> </wicket:head> <body> Stuff goes here! </body> </html> 4. Now create the css file that uses the variables (place it next to MyPage.java)style.css
body
{
background: ${color1};
}
5. Clustered EnvironmentsBe careful as the above approach will not work out of the box for a clustered environment. For example, if server1 and server2 sit behind a loadbalancer and your wicket app is freshly started it might happen, that the first user gets directed to server1, from which he gets the start page. This page may include dynamic css like above which the browser now loads in a separate request which maybe gets delegated to server2, which maybe has never initialized the start page. Now the wicket app from server2 serves the css without resolving the variables.
Change Notification Preferences
View Online
|
View Changes
|
Add Comment
|
- [CONF] Apache Wicket > Dynamically Generate a CSS Stylesheet confluence
