views:

167

answers:

4

Hello

I have a text template with placehoders that I parse in order to replace placeholders with real values.

Text Template:

Name:%name%
Age:%age%

I use StringBuilder.Replace() to replace placeholders

sb.Replace("%name%", Person.Name);

Now I want to make more advanced algorithm. Some lines of code are conditional. They have to be either removed completely of kept.

Text Template

Name:%Name%
Age:%age%
Employer:%employer%

The line Employer should appear only when person is employed (controlled by boolean variable Person.IsEmployed).

UPDATE: I could use open/close tags. How can find text between string A and B? Can I use Regex? How?

+3  A: 

Perhaps you could include the label "Employer:" in the replacement text instead of the template:

Template:

Name:%Name%
Age:%age%
%employer%

Replacement

sb.Replace("%employer%", 
    string.IsNullOrEmpty(Person.Employer) ? "" : "Employer: " + Person.Employer)
Fredrik Mörk
How can I set that the label relates only to specific region of text?I think I need to introduce opening/closing tags.
Captain Comic
+1  A: 

One option would be to do all of your replacement as you're doing now, then fix empty variables with a RegEx replacement on the way out the door. Something like this:

Response.Write(RegEx.Replace(sb.ToString(), "\r\n[^:]+:r\n", "\r\n"));
richardtallent
+2  A: 

Another alternative might be to use a template engine such as Spark or NVelocity.

See a quick example for Spark here

A full-fledged template engine should give you the most control over the formatted output. For example conditionals and repeating sections.

Philip Fourie
+1  A: 

Your current templating scheme isn't robust enough - you should add more special placeholders, like this for example:

Name:%Name%
Age:%age%
[if IsEmployed]
Employer:%employer%
[/if]

You can parse out [if *] blocks using a regex (not tested):

Match[] ifblocks = Regex.Match(input, "\\[if ([a-zA-Z0-9]+)\\]([^\\[]*)\\[/if\\]");
foreach(Match m in ifblocks) {
    string originalBlockText = m.Groups[0];
    string propertyToCheck = m.Groups[1];
    string templateString = m.Groups[2];

    // check the property that corresponds to the keyword, i.e. "IsEmployed"

    // if it's true, do the normal replacement on the templateString
    // and then replace the originalBlockText with the "filled" templateString

    // else, just don't write anything out
}

Really, though, this implementation is full of holes... You may be better off with a templating framework like another answer suggested.

Jeff Meatball Yang