This is going to be a quick one, at least in terms of commentary.
This site is 100% static HTML. This is because I don't want to spend the rest of my life patching Wordpress. I know there are many other alternatives but I'm perfectly happy to keep this static HTML. Way, way back in the early days (2000ish) I managed this site in Microsoft FrontPage but ultimately it was still just static HTML.
Despite that, I have a bunch of code to maintain the site. Eventually I'll post about it in more detail. It handles things like rewriting the header, footer, and navigation to all HTML pages whenever I make a change.
For the longest time I had stuff like CSS versions hardcoded. That is not good but I only run this on my PC so who cares? I'd like to post my little web publishing system on Github eventually though. I need to fix bad things like this so I don't look inept (I know, too late).
I'm aware of multiple libraries to handle templates but I decided to write my own because it's very easy. The requirements go like:
Here's the code I came up with:
/* MIT license */
import java.util.HashMap;
import java.util.Map;
public class SimpleTemplater{
//default delimiter
public final static String DEFAULT_TEMPLATE_START="{";
public final static String DEFAULT_TEMPLATE_END="}";
private Map<String,String> staticTemplates;
private String templateStart=DEFAULT_TEMPLATE_START;
private String templateEnd=DEFAULT_TEMPLATE_END;
public SimpleTemplater(Map<String,String> staticTemplates){
this.staticTemplates=staticTemplates;
}
public SimpleTemplater(Map<String,String> staticTemplates,String templateStart,String templateEnd){
this.staticTemplates=staticTemplates;
this.templateStart=templateStart;
this.templateEnd=templateEnd;
}
public String process(String s){
StringBuffer sb=new StringBuffer(s);
int startIndex=sb.indexOf(this.templateStart);
int endIndex=sb.indexOf(this.templateEnd);
while(
(startIndex>=0)&&
(startIndex<sb.length())&&
(endIndex>0)&&
(endIndex<sb.length())
)
{
if(endIndex>startIndex){
//we have something
String match=sb.substring(startIndex,endIndex+1);
//test if this is a static template
String staticReplace=this.staticTemplates.getOrDefault(match,null);
if(staticReplace!=null){
//replace the template with the value
sb.replace(startIndex,endIndex+1,staticReplace);
//next starting point should be at the end of the block just replaced
startIndex=startIndex+staticReplace.length();
endIndex=startIndex+1;
}else{
//increment indexes
startIndex++;
endIndex=startIndex+1;
}
}else{ //endIndex<startIndex so there is a mismatched tag
endIndex=startIndex+1;
}
//search for next template match
startIndex=sb.indexOf(this.templateStart,startIndex);
endIndex=sb.indexOf(this.templateEnd,endIndex);
}
return(sb.toString());
}
}
This is probably (certainly) not the most efficient solution to the problem. My entire web publisher app, which includes this code, runs against every page in this site in roughly 1 second. If it ever takes 2 seconds then I'll look into optimizing it. It's a very simple scheme to swap string values which is what I needed.
Here is a JUnit test for this code:
/* also MIT license */
class TestSimpleTemplater{
@Test
void testStaticTemplates(){
//setup some data
Map<String,String> staticTemplates=new HashMap<String,String>();
staticTemplates.put("{TESTKEY1}","TESTVALUE1");
staticTemplates.put("{TESTKEY2}","TESTVALUE2");
staticTemplates.put("{TESTKEY3}","TESTVALUE3");
//setup templater
SimpleTemplater templater=new SimpleTemplater(staticTemplates);
//simple tests
String templateString="{TESTKEY1}";
String expectedResult="TESTVALUE1";
String resultString=templater.process(templateString);
assertEquals(expectedResult,resultString);
templateString="{TESTKEY1";
expectedResult="{TESTKEY1";
resultString=templater.process(templateString);
assertEquals(expectedResult,resultString);
templateString="{XSS_VERSION}";
expectedResult="{XSS_VERSION}";
resultString=templater.process(templateString);
assertEquals(expectedResult,resultString);
templateString="blah{TESTKEY1}blah";
expectedResult="blahTESTVALUE1blah";
resultString=templater.process(templateString);
assertEquals(expectedResult,resultString);
templateString="{TESTKEY2}";
expectedResult="TESTVALUE2";
resultString=templater.process(templateString);
assertEquals(expectedResult,resultString);
templateString="{TESTKEY3}";
expectedResult="TESTVALUE3";
resultString=templater.process(templateString);
assertEquals(expectedResult,resultString);
//longer tests
templateString="blah{TESTKEY1}blah{TESTKEY2}blah{TESTKEY3}";
expectedResult="blahTESTVALUE1blahTESTVALUE2blahTESTVALUE3";
resultString=templater.process(templateString);
assertEquals(expectedResult,resultString);
templateString="blah{TESTKEY1blah{TESTKEY2}blah{TESTKEY3}";
expectedResult="blah{TESTKEY1blahTESTVALUE2blahTESTVALUE3";
resultString=templater.process(templateString);
assertEquals(expectedResult,resultString);
templateString="blah{TESTKEY1}blahTESTKEY2}blah{TESTKEY3}";
expectedResult="blahTESTVALUE1blahTESTKEY2}blahTESTVALUE3";
resultString=templater.process(templateString);
assertEquals(expectedResult,resultString);
//oddball tests
templateString="blah{{TESTKEY1}blah";
expectedResult="blah{TESTVALUE1blah";
resultString=templater.process(templateString);
assertEquals(expectedResult,resultString);
templateString="blah{TESTKEY1}}blah";
expectedResult="blahTESTVALUE1}blah";
resultString=templater.process(templateString);
assertEquals(expectedResult,resultString);
templateString="blah{{TESTKEY1}}blah";
expectedResult="blah{TESTVALUE1}blah";
resultString=templater.process(templateString);
assertEquals(expectedResult,resultString);
}
}
The latest version of this code will be here. It's possible I will make it more efficient or more complicated.
Related