Templating support #3393
Replies: 16 comments
-
Perhaps just add T4 support using sdk TextTransform.exe, that could also enable recompiling .tt files in cake build scripts. T4 is well tested and basically just "asp" for codegen. |
Beta Was this translation helpful? Give feedback.
-
T4 support would be very nice indeed, but I was thinking about something really lightweight that doesn't require TextTransform.exe. |
Beta Was this translation helpful? Give feedback.
-
new Template("How about {word} like this?").Render(new Dictionary<string,string>({{"word", "something"}})); |
Beta Was this translation helpful? Give feedback.
-
Yes, something like that. Just to make it simple to do very simple transformastions such as setting a version number in a file or something similar. However, I think T4 support would be very nice as well :) |
Beta Was this translation helpful? Give feedback.
-
Here's something I use in production :) https://gist.github.com/rofr/ab9b6868f81c09b8aa79 |
Beta Was this translation helpful? Give feedback.
-
I've written a couple DSLs with help of RegEx;) you can indeed with fairly simple measures solve complex scenarios. As long as you keep a limited scope it can be very useful. But can also be a rabbit hole ;) Personally I wouldn't mind the TextTransform.exe dependency, passing an assembly and/or parameters (-a !!param!value) could enable a simple view model to apply the template on. You can also host the T4 engine but wouldn't recommend that. |
Beta Was this translation helpful? Give feedback.
-
What about just adding mustasche? Sent from my iPhone
|
Beta Was this translation helpful? Give feedback.
-
I've been doing some investigation and come to the conclusion that T4-templating will not be used for this since it has a dependency on I've prototyped a simple API that I will try to implement and try out. TransformText("{greeting} {word}!")
.WithToken("greeting", "Hello")
.WithToken("word", "World")
.Save("./transformed.txt"); TransformText("{greeting} {word}!")
.WithToken("greeting", "Hello")
.WithToken("word", "World")
.ToString(); TransformTextFile("./template.txt")
.WithToken("greeting", "Hello")
.WithToken("word", "World")
.Save("./transformed.txt"); Any thoughts or suggestions? |
Beta Was this translation helpful? Give feedback.
-
Looks nice, |
Beta Was this translation helpful? Give feedback.
-
Yes, that's a great idea. Actually, both var tokens = new Dictionary<string, object>
{
{ "name", "Patrik" }
{ "age", 12 },
}
TransformText("{greeting} {name}!", tokens)
.WithToken("greeting", "Hello")
.Save("./transformed.txt"); Got a better name for |
Beta Was this translation helpful? Give feedback.
-
Perhaps use more rare token identifier i.e. private static readonly Regex TokenRegex = new Regex(
"<%(?![#$])(([^%]*)%)*?>",
RegexOptions.Singleline | RegexOptions.Compiled
);
internal static string RenderedTemplate(
string template,
IDictionary<string, object> tokens,
IFormatProvider culture = null
)
{
var renderedTemplate = TokenRegex.Replace(
template,
match => tokens.ReplaceToken(
match,
culture ?? CultureInfo.InvariantCulture
)
);
return renderedTemplate;
}
private static string ReplaceToken(
this IDictionary<string, object> tokens,
Match match,
IFormatProvider culture = null
)
{
var token = match.Groups
.OfType<Group>()
.Select(group => @group.Value)
.LastOrDefault()
?? match.Value.Trim('<', '%', '>');
var key = string.Concat(
token
.Select(CultureInfo.InvariantCulture.TextInfo.ToLower)
.TakeWhile(
c => c != ':'
)
);
var format = string.Format(
"{{0{0}}}",
string.Concat(
token
.SkipWhile(
c => c != ':'
)
)
);
object value;
switch (key)
{
case "now":
value = DateTime.Now;
break;
case "utcnow":
value = DateTime.UtcNow;
break;
default:
value = tokens.TryGetValue(key, out value)
? string.Format(
culture ?? CultureInfo.InvariantCulture,
format,
value
)
: match.Value;
break;
}
return string.Format(
culture,
format,
value
);
} Could be used something like this var tokens = new Dictionary<string, object>(StringComparer.OrdinalIgnoreCase)
{
{"greeting", "Hello"},
{"firstname", "John"},
{"lastname", "Doe"},
{"age", 25},
{"offer", 125.3555m}
};
var renderedTemplate = RenderedTemplate(
@"<%greeting%> <%firstname%> <%lastname%>,
you are <%age%> years old.
Special price for you is <%offer:c2%>
Template generated <%now:yyyy-MM-dd HH:mm:ss%> (Utc: <%utcnow:yyyy-MM-dd HH:mm:ss%>)
",
tokens,
new CultureInfo("sv-SE")
);
Information(renderedTemplate); Outputing something like:
one could get a group for format to... but above should illustrate what I mean;) |
Beta Was this translation helpful? Give feedback.
-
I like the idea, but I would want to keep this kind of templating support very, very simple. Of course, nothing prevents us from expanding it by building on top of it when it's ready, but for the time being I think there is a clear benefit of keeping it as simple as possible until we know what we want. Maybe a T4 tool wrapper would be a better approach? |
Beta Was this translation helpful? Give feedback.
-
Isn't above very simple? Just a regex, switch and a dictionary?;) More advanced features could indeed be added later. Yeah think T4 should be it's own tool. |
Beta Was this translation helpful? Give feedback.
-
The code is very simple and readable, but the functionality itself isn't. By providing "expressions" like Please note that I'm not against your suggestion. I just think it feels better to keep the templating functionality to a minimum until we know what kind of functionality we want. I don't want to be a dictator here so of course I want a discussion about this 😄 I don't know. Could we limit the scope of this? Include hard coded expression? Include custom expressions? What do you think? |
Beta Was this translation helpful? Give feedback.
-
well remove the switch then;) |
Beta Was this translation helpful? Give feedback.
-
I'd throw in my two cents and say that I'd be a fan of including https://github.com/jehugaleahsa/mustache-sharp. I would say, though, that anything beyond string.Format() is going to be complex by it's nature very quickly and it'd be better to bring in a full fledged engine from the start. |
Beta Was this translation helpful? Give feedback.
-
Would be nice with some kind of templating support to easily replace tokens in a template to produce an new file. For example; setting the
Version
property in apsd1
template to produce a new file.With this in place, other templating stuff in Cake such as nuspec transformations could just be a wrapper around this functionality.
Beta Was this translation helpful? Give feedback.
All reactions