I've started using ESI's in Akamai. They work perfectly fine when I've got a site running on int/test/stage/production environments which actually run through Akamai.
However, when we work locally on a PC, we tend to just use a simple jetty server and the site is not served using Akamai. This makes it a bit challenging to see if the work is correct without deploying our solution to Akamai.
Is there a way to simulate an ESI locally for development without using Akamai?
I could not find any official way of doing this, so I emulated a ESI on the server side as if it were an SSI, using an IF statement in our freemarker.
I use spring, freemarker + java to do this solution:
1) Create a macro that will decide to use the ESI or emulate it via SSI if running local (noescape may not be required, depends how you have set things up)
<#macro esi url>
<#if esiUrl?contains("localhost")>
<#noescape>${ssiInclude(url)}</#noescape>
<#else>
<esi:include src="${esiUrl}/${url}" />
</#if>
</#macro>
2) use the macro with the url <@html.esi url="my/url" />
3) Exposed the SSI Include method in java/spring (you'll need to have setup some environment specific values for esiUrl and the sites base url)
<bean id="freemarkerViewResolver" class="org.springframework.web.servlet.view.freemarker.FreeMarkerViewResolver">
......
<property name="attributesMap" ref="staticAttributesMap"/>
</bean>
<util:map id="staticAttributesMap">
<entry key="esiUrl" value="${esi.url}" />
<!-- formatters -->
<entry key="ssiInclude" >
<bean class="com.channel4.bips.web.freemarker.SsiIncludeMethodModel">
<property name="urlBase" value="${base.url}/"/>
</bean>
</entry>
</util:map>
4) The java to emulate a SSI in freemarker
import freemarker.template.TemplateMethodModel;
import freemarker.template.TemplateModelException;
import org.apache.commons.lang.Validate;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.Reader;
import java.net.URL;
import java.util.List;
public class SsiIncludeMethodModel implements TemplateMethodModel {
private String urlBase;
@Override
public Object exec(List list) throws TemplateModelException {
String uri = (String) list.get(0);
Validate.notNull(uri);
return readContents(urlBase + uri.trim());
}
public String readContents(String address) {
StringBuilder contents = new StringBuilder(2048);
BufferedReader br = null;
try {
URL url = new URL(address);
br = new BufferedReader(new InputStreamReader(url.openStream()));
String line;
while ((line = br.readLine()) != null) {
contents.append(line);
}
} catch (IOException x) {
x.printStackTrace();
return "Error getting SSI data";
} finally {
close(br);
}
return contents.toString();
}
private static void close(Reader br) {
try {
if (br != null) {
br.close();
}
} catch (Exception e) {
e.printStackTrace();
}
}
public void setUrlBase(String urlBase) {
this.urlBase = urlBase;
}
}