simplified template engine. Doesn't need to be async