views:

110

answers:

1

I'm trying to build a simple "User Template" system so that my users can edit the layout of RSS feed items and system-generated emails without messing with view files and such. This is the function I'm using to replace the tags in a string with content:

private const string URL_TAG_REGEX = @"{{(?<TagName>\w*)}}";
private static string ReplaceTags(string content, 
    Dictionary<string, object> values) {
        Regex r = new Regex(UT_TAG_REGEX);
        foreach (string tag in values.Keys) {
            content = r.Replace(content, 
                m => (m.Groups["TagName"].Value == tag ? 
                    values[tag].ToString() : string.Empty));
        }
    return content;
}

My test template looks like this:

<a href="{{link}}">{{title}}</a> - {{date}}<br />
{{description}}

and is being rendered with this:

<%= UserTemplates.Render("overview_rss_item", new {
        link = item.Link,
        title = item.Title,
        date = item.PublishDate,
        description = item.Description
    }) %>

The Render method takes care of opening the file and converting the anonymous object to a Dictionary. It mostly works, except that only the {{link}} tag is being matched. The rest are being replaced with string.Empty.

A: 

Because you are replacing all the matches, and if the value doesn't equal the tag, you're replacing it with String.Empty. Try this:

    foreach (string tag in values.Keys) {
        content = r.Replace(content, 
            m => (m.Groups["TagName"].Value == tag ? 
                values[tag].ToString() : m.Value));
    }
scwagner
Wow what a dumb mistake. For some reason I was thinking that Replace would only try to match one tag at a time. Thanks!
David Brown