axuno / SmartFormat

A lightweight text templating library written in C# which can be a drop-in replacement for string.Format
Other
1.09k stars 104 forks source link

For-Loop #10

Closed SeriousM closed 11 years ago

SeriousM commented 11 years ago

Hi,

I'm searching for a formatting library that is easy to read/write and can do exactly what yours can, at least it looks like that.

Some Questions:

  1. are dynamic objects supported
  2. is the case important -> TEst == teST?
  3. Can I write an extension to support loops like {#for Items}{Name}{#forend}

Thanks for this library!!

Cheers!

scottrippey commented 11 years ago

Thanks for your feedback!

  1. I created this library before -.NET 4.0, so I didn't include dynamic support. However, it should be easy to add support; take a look at the DictionarySource extension for a good example.
  2. The Reflection feature is case-sensitive. It could probably be modified to be case-insensitive. Or, since Dictionary is supported, you could create a case-insensitive Dictionary to hold your values, and it would work just fine.
  3. There is built-in support for "list formatting", which might suit your case. It's intentionally simple, but supports nesting, so it's pretty useful. https://github.com/scottrippey/SmartFormat.NET/wiki#list-formatting

If you create a DynamicSource (for 1), I'd love to include it here, so let me know.

SeriousM commented 11 years ago

Hi, the list formatting is too less for my needs...

My template would look like this:

<catalog itemcount="{Items.Count}">
{for Items}
<item name="{Name}" price="{Price:c}" />
{/for}
</catalog>

This is just an example but shows what I need to achieve. Can I achieve that by preprocessing the template first? An index number would be cool but is not necessary.

Cheers and thanks!

scottrippey commented 11 years ago

You can achieve what you wanted by using nested placeholders:

<catalog itemcount="{Items.Count}">
{Items:
    <item name="{Name}" price="{Price:c}" />
    And yes, you can also use {Index}
}
</catalog>

Everything inside the {Items:*} placeholder will be repeated for each item.

SeriousM commented 11 years ago

Wow, thats awesome! I didn't know that I can write the "loop" over multiple lines!

Regarding the case-sensitive thing: did you know that you can create a case-insensitive dictionary like that: new Dictionary<string, object>(StringComparer.InvariantCultureIgnoreCase)

The other way around that problem could be to use the DataBinder.Eval function described here (which I'm using at the moment): http://james.newtonking.com/archive/2008/03/29/formatwith-2-0-string-formatting-with-named-variables.aspx

Is there a way to support that natively by your library?

scottrippey commented 11 years ago

Re: The case-insensitive dictionary is what I was suggesting for # 2 ... that's probably the easiest built-in way for doing case-insensitive values.

Re: DataBinder.Eval - I would be hesitant to replace the current ReflectionSource.cs with something that used DataBinder ... mostly because I like the explicit control with Reflection, and I want to keep this lightweight. Also, I didn't want to create a dependency on the System.Web.UI namespace. So that's why I decided to write a custom Reflection-based evaluator. Anyway, I think (but I'm not certain) that Reflection has the ability to be case-insensitive, but I didn't implement it that way. It might be a nice feature to default to case-insensitive.

SeriousM commented 11 years ago

I have good news for you! The method Type.GetMember(string) you're using can have a flag to ignore the case: this.GetType().GetMember("name of the member", System.Reflection.MemberTypes.All, System.Reflection.BindingFlags.IgnoreCase); Could you tell me how to implement that / could you implement it because you're knowing the system better than me?

Cheers!

scottrippey commented 11 years ago

@SeriousM Good find ... that's probably the best solution.

The bad news, though, is that I'm unable to implement that change right now ... I haven't been working in .NET for a while now, and I don't have my dev environment set up. This sounds like a simple change, but I'd want to create Unit Tests for it and everything.

So, I'm not sure how "open-source savvy" you are, but if you'd like to contribute to this project, I'd be happy to pull in your change request.

SeriousM commented 11 years ago

I'm very open-sourcy ;) As you may have recognized I forked your repo already.

I will do my best to bring this change into the code. Btw: how do you like to handle the default values, is there a configuration object somewhere?

scottrippey commented 11 years ago

No, but I'm open to suggestions. The use-case for this code was so basic, that I've always used the default options. But it would be a good idea to support configuration for options like case-sensitivity, or to configure the list of default extensions, etc.

SeriousM commented 11 years ago

Ok, I will change the code over the weekend including:

can i submit these changes then as one pull request or do you want to have multiple ones which makes the process slower?

Cheers

SeriousM commented 11 years ago

ok, I changed already some code. you can have a look at it if you like :) https://github.com/SeriousM/SmartFormat.NET/compare/2a67ecf2e024c1cd2db10b31d9ce4dfceec24919...HEAD

linudaar commented 11 years ago

great job! looking forward to seeing the case insensitivity ;-)

SeriousM commented 11 years ago

Alright, the pull request is created: https://github.com/scottrippey/SmartFormat.NET/pull/11

SeriousM commented 11 years ago

I'll close this one, pull request is enough :)