public class EmailLogic { public static String renderTemplate(sObject sobj, String template) { for (String fieldName : fields(sobj.getSObjectType())) { String key = '{!' + fieldName + '}'; while (template.containsIgnoreCase(key)) { try { Integer foundPosition = template.indexOfIgnoreCase(key, 0); template = template.left(foundPosition) + String.valueOf(sobj.get(fieldName)) + template.substring(foundPosition + key.length()); } catch (Exception e) { // ignoring field not queried error for now because not sure if we want to query everything } } } return template; } public static String renderTemplate(Id id, String template) { Schema.sObjectType t = id.getSObjectType(); String query = 'select ' + joinStrings(',', queryableFields(t)) + ' from ' + t + ' where Id = :id '; for (sObject sobj : Database.query(query)) { return renderTemplate(sobj, template); } return null; } private static String joinStrings (String delimiter, Set items) { String result = ''; for (String item : items) { if (result != '') result += delimiter; result += item; } return result; } private static Set fields(Schema.sObjectType t) { Set result = new Set(); Map fields = t.getDescribe().fields.getMap(); return fields.keySet(); } private static Set editableFields(Schema.sObjectType t) { Set result = new Set(); Map fields = t.getDescribe().fields.getMap(); for(String fieldName : fields.keySet()) { if(fields.get(fieldName).getDescribe().isUpdateable()) { result.add(fieldName); } } return result; } private static Set queryableFields(Schema.sObjectType t) { Set result = new Set(); Map fields = t.getDescribe().fields.getMap(); for(String fieldName : fields.keySet()) { if(fields.get(fieldName).getDescribe().isUpdateable()) { result.add(fieldName); } } return result; } private static Set createableFields(Schema.sObjectType t) { Set result = new Set(); Map fields = t.getDescribe().fields.getMap(); for(String fieldName : fields.keySet()) { if(fields.get(fieldName).getDescribe().isCreateable()) { result.add(fieldName); } } return result; } }