How to use a resx resource file in a T4 template
Asked Answered
N

4

5

I cant figure out how to include the resource file (.resx) in the (.tt) T4 template.

I tried so far... Importing the namespace

<#@ import namespace="T4TemplateResources.resx" #>

Also including the class

Nigh answered 8/4, 2013 at 17:32 Comment(2)
has your resx been compiled?Himation
The import statement adds the equivalent of using statements to C# (import in VB) to resolve namespaces implicitly - it doesn't bring any file into the template. Can you elaborate a little on what you're trying to achieve please?Koh
D
3

Nico's solution requires your solution to build.

There is another way, without needing to compile your solution by reading the raw resx file.

    var fileName = "CustomResource.resx";
    var filePath = Path.Combine(Path.GetDirectoryName(this.Host.ResolvePath("")), "WindowsFormsApplication1", fileName);
    var reader = new ResXResourceReader(filePath);
    var values = reader.Cast<DictionaryEntry>().ToDictionary(x => x.Key, y => y.Value);

    // this is how you would acces the resources
    var value = values["entry"];

You should be aware that this method lacks design time checking if the resource does not exist and you don't get localized values because you are just reading a file. Both are often not mandatory withing T4 templates

Here is a working snipped that creates an enum from a resource file.

Just make sure you use set the right values for fileName and filePath

<#@ template debug="false" hostspecific="true" language="C#" #>
<#@ output extension=".cs" #>
<#@ assembly name="System.Windows.Forms" #>

<#@ import namespace="System.Resources" #>
<#@ import namespace="System.Collections" #>
<#@ import namespace="System.IO" #>
<#@ import namespace="System.ComponentModel.Design" #>

<#

    var nameSpace = "WindowsFormsApplication1";
    var enumName = "CustomEnum";

    var fileName = "CustomResource.resx";
    var filePath = Path.Combine(Path.GetDirectoryName(this.Host.ResolvePath("")), "WindowsFormsApplication10", fileName);

    using (var reader = new ResXResourceReader(filePath))
    {

        reader.UseResXDataNodes = true;
#>

namespace <#=nameSpace#>
{

    public enum <#=enumName#>
    {

        Undefined,

        <#  foreach(DictionaryEntry entry in reader) { 

            var name = entry.Key;
            var node = (ResXDataNode)entry.Value;
            var value = node.GetValue((ITypeResolutionService) null);
            var comment = node.Comment;
            var summary = value;
            if (!String.IsNullOrEmpty(comment)) summary += " - " + comment;
        #>

        /// <summary>
        /// <#= summary #>
        /// </summary>
        <#= name #>,

        <# } #>

    }

}


<#
    }
#>
Damnation answered 6/12, 2013 at 9:3 Comment(0)
I
2

Sample T4 template code for reading from the Resources (.resx) and creating a JS file with the JSON result for the resources:

<#@ template debug="true" hostspecific="true" language="C#" #>
<#@ assembly name="System.Core" #>
<#@ assembly name="$(TargetPath)" #>
<#@ assembly name="System.Windows.Forms" #>
<#@ import namespace="System.Linq" #>
<#@ import namespace="System.Resources" #>
<#@ import namespace="System.Collections" #>
<#@ import namespace="System.IO" #>
<#@ import namespace="System.Text" #>
<#@ import namespace="System.Collections.Generic" #>
<#@ output extension=".js" #>
<# 
    var path = Path.GetDirectoryName(Host.TemplateFile);
    var resourceNames = new string[1]
    {
        "Resources"
    };
#>
var $.Resources = {
<# foreach ( var name in resourceNames ) {
    var localeFile = Host.ResolvePath(path + "\\" + name + ".resx");
    ResXResourceSet jpResxSet = new ResXResourceSet(localeFile);
#>
<# foreach (DictionaryEntry item in jpResxSet) { #>
    '<#=item.Key.ToString()#>' : '<#= ("" + item.Value).Replace("\r\n", string.Empty).Replace("'", "\\'")#>',
<# } #>
<# } #>
};

Kudos to Jochen van Wylick: Using T4 for localizing JavaScript resources based on .resx files

Immersed answered 24/4, 2015 at 0:26 Comment(0)
T
0

If you want to access the resources of a .resx-File from within a T4 template, this is how you would do it:

  1. In the Resource Editor set the Access Modifier for the resources to "Public".
  2. Make sure your project builds successfully. The t4 template can only access the output assembly - so check if it's up to date.
  3. Reference the output assembly in the T4 template (you can use Visual Studio Macros here): <#@ assembly name="$(TargetDir)\outputfile.ext" #>
  4. Import the namespace of the ResourceFile in the T4 template <#@ import namespace="MyNamespace" #>

Then you can access the resources as usually:

<# var theResource = Resource1.TheResource; #>
Trawler answered 15/4, 2013 at 6:20 Comment(0)
R
0

There is an easier way to do this without compiling your project if you are using VS2010 SP1 and above, by using

<#@ assembly name="$(TargetPath)" #>
<#@ import namespace="Your.Namespace.Properties" #>

Copy the first line as it is, and in the second line use the namespace where the Resource file resides and access the resource strings normally as you would in c#

Resources.ResourceManager.GetString("SomeKey");

or

var key = Resources.SomeKey;

I learnt this from Use class inside a T4 template

Hope it helps somebody

Resinate answered 13/11, 2014 at 16:19 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.