Question

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?

Was it helpful?

Solution

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.

OTHER TIPS

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)

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.

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"));
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top