コード例 #1
0
        public void TestMustacheTemplateProcessSingleTemplateWithNoScriptShouldWork()
        {
            // 1. Prepare template
            var    templateName = "NoScript";
            string template     = @"
{{#model}}
name1={{name1}},
name2={{name2}};
{{/model}}
";
            var    model        = new
            {
                model = new object[]
                {
                    new { name1 = "test1" },
                    new { name2 = "test2" },
                }
            };
            var modelFileName = Path.Combine(_inputFolder, "TestTemplateProcessor_NoScript.yml");
            var item          = new InternalManifestItem {
                DocumentType = string.Empty, Key = modelFileName, FileWithoutExtension = Path.ChangeExtension(modelFileName, null), ResourceFile = modelFileName
            };

            ProcessTemplate(templateName, null, new[] { item }, model, _outputFolder, Tuple.Create("default.tmpl", template));

            var outputFile = Path.Combine(_outputFolder, Path.ChangeExtension(modelFileName, string.Empty));

            Assert.True(File.Exists(outputFile));
            Assert.Equal(@"
name1=test1,
name2=;
name1=,
name2=test2;
", File.ReadAllText(outputFile));
        }
コード例 #2
0
        public void JsCreateDateShouldNotThrowError()
        {
            var    templateName    = "TemplateFolder.html";
            string defaultTemplate = @"{{date}}";
            string script          = @"
exports.transform = function (model){
    return {
        date: new Date(new Date('2019-08-19T05:40:30.4629999Z')).toISOString()
    };
}";

            var model = new object();
            var item1 = new InternalManifestItem
            {
                FileWithoutExtension = "file",
                Key               = "x.yml",
                DocumentType      = "Conceptual",
                LocalPathFromRoot = "file.md",
            };

            ProcessTemplate(templateName, null, new[] { item1 }, model, _outputFolder,
                            Tuple.Create("default.html.tmpl", defaultTemplate),
                            Tuple.Create("default.html.js", script)
                            );
            var outputFilePath1 = Path.Combine(_outputFolder, "file.html");

            Assert.True(File.Exists(outputFilePath1));
            Assert.Equal("2019-08-19T05:40:30.000Z", File.ReadAllText(outputFilePath1));
        }
コード例 #3
0
        public void TestLiquidTemplateProcessSingleTemplateWithNoScriptShouldWork()
        {
            // 1. Prepare template
            var    templateName = "NoScript.liquid";
            string template     = @"
{% for item in model -%}
{{ item.name }}
{% endfor -%}
";
            var    model        = new
            {
                model = new[]
                {
                    new { name = "test1" },
                    new { name = "test2" },
                }
            };
            var modelFileName = Path.Combine(_inputFolder, "TestLiquidTemplateProcessor_NoScript.yml");
            var item          = new InternalManifestItem {
                DocumentType = string.Empty, Key = modelFileName, FileWithoutExtension = Path.ChangeExtension(modelFileName, null), ResourceFile = modelFileName
            };

            ProcessTemplate(templateName, null, new[] { item }, model, _outputFolder, Tuple.Create("default.liquid", template));

            var outputFile = Path.Combine(_outputFolder, Path.ChangeExtension(modelFileName, string.Empty));

            Assert.True(File.Exists(outputFile));
            Assert.Equal(@"
test1
test2
", File.ReadAllText(outputFile));
        }
コード例 #4
0
        public void TestMustacheTemplateProcessTemplateFolderWithDifferentTypeShouldWork()
        {
            var    templateName       = "TemplateFolder.html";
            string defaultTemplate    = @"
default:
{{#model}}
{{name}}
{{/model}}
";
            string conceptualTemplate = @"
conceptual:
{{#model}}
{{name}}
{{/model}}
";
            string script             = @"
exports.transform = function (model){
    model.model.push({name:'test2'});
    return model;
}";

            var model = new
            {
                model = new List <object>
                {
                    new { name = "test1" },
                }
            };

            string inputFolder = null;
            var    item1       = new InternalManifestItem {
                FileWithoutExtension = "TestTemplateProcessor_TemplateFolderWithDifferentType1", Key = "x.yml", DocumentType = "Conceptual"
            };
            var item2 = new InternalManifestItem {
                DocumentType = string.Empty, FileWithoutExtension = "TestTemplateProcessor_TemplateFolderWithDifferentType2", Key = "y.yml"
            };

            ProcessTemplate(templateName, inputFolder, new[] { item1, item2 }, model, _outputFolder,
                            Tuple.Create("default.html.tmpl", defaultTemplate),
                            Tuple.Create($"{templateName}/conceptual.md.tmpl", conceptualTemplate),
                            Tuple.Create("default.html.js", script),
                            Tuple.Create("conceptual.md.js", script)
                            );
            var outputFilePath1 = Path.Combine(_outputFolder, "TestTemplateProcessor_TemplateFolderWithDifferentType1.md");

            Assert.True(File.Exists(outputFilePath1));
            Assert.Equal(@"
conceptual:
test1
test2
", File.ReadAllText(outputFilePath1));
            var outputFilePath2 = Path.Combine(_outputFolder, "TestTemplateProcessor_TemplateFolderWithDifferentType2.html");

            Assert.True(File.Exists(outputFilePath2));
            Assert.Equal(@"
default:
test1
test2
", File.ReadAllText(outputFilePath2));
        }
コード例 #5
0
        public void TestMustacheTemplateProcessSingleTemplateWithRequireScriptShouldWork()
        {
            var templateName = "WithRequireScript.html";

            string template   = @"
{{#model}}
{{#result1}}result1 = true{{/result1}}
{{#result2}}result2 = true{{/result2}}
{{#result3}}result3 = true{{/result3}}
{{/model}}
";
            string mainScript = @"
var util = require('./util.js');

exports.transform = function (model){
    var url = 'https://www.microsoft.com';
    model.model.result1 = util.isAbsolutePath(url);
    model.model.result2 = util.isAbsolutePath(url);
    model.model.result3 = util.isAbsolutePath(url);
    return model;
}";
            string utilScript = @"
exports.isAbsolutePath = isAbsolutePath;

function isAbsolutePath(path) {
    return /^(\w+:)?\/\//g.test(path);
}
";

            var model = new
            {
                model = new Dictionary <string, object>()
            };

            var    modelFileName = Path.Combine(_inputFolder, "TestTemplateProcessor_WithRequireScript.yml");
            string inputFolder   = null;
            var    item          = new InternalManifestItem
            {
                FileWithoutExtension = Path.ChangeExtension(modelFileName, null),
                DocumentType         = string.Empty,
                Key = modelFileName,
                LocalPathFromRoot = modelFileName,
            };

            ProcessTemplate(templateName, inputFolder, new[] { item }, model, _outputFolder,
                            Tuple.Create("default.html.tmpl", template),
                            Tuple.Create("default.html.js", mainScript),
                            Tuple.Create("util.js", utilScript)
                            );
            var outputFilePath = Path.Combine(_outputFolder, Path.ChangeExtension(modelFileName, "html"));

            Assert.True(File.Exists(outputFilePath));
            AssertEqualIgnoreCrlf(@"
result1 = true
result2 = true
result3 = true
", File.ReadAllText(outputFilePath));
        }
コード例 #6
0
        public void TestMustacheTemplateProcessSingleTemplateWithNoScriptWithPartialShouldWork()
        {
            // 1. Prepare template
            var    templateName = "Subfolder/NoScriptWithPartial";
            string template     = @"
{{#model}}
{{name}}
{{/model}}
{{>partial1}}
";
            string partial1     = @"partial 1:
{{>partial2}}";
            string partial2     = @"partial 2:
{{#model}}
{{name}}
{{/model}}
";
            var    model        = new
            {
                model = new[]
                {
                    new { name = "test1" },
                    new { name = "test2" },
                }
            };
            var modelFileName = Path.Combine(_inputFolder, "TestTemplateProcessor_NoScriptWithPartial.yml");
            var item          = new InternalManifestItem
            {
                DocumentType         = string.Empty,
                Key                  = modelFileName,
                FileWithoutExtension = Path.ChangeExtension(modelFileName, null),
                ResourceFile         = modelFileName,
                LocalPathFromRoot    = modelFileName,
            };

            ProcessTemplate(
                templateName,
                null,
                new[] { item },
                model,
                _outputFolder,
                Tuple.Create("default.tmpl", template),
                Tuple.Create("partial1.tmpl.partial", partial1),
                Tuple.Create("partial2.tmpl.partial", partial2));

            var outputFile = Path.Combine(_outputFolder, Path.ChangeExtension(modelFileName, string.Empty));

            Assert.True(File.Exists(outputFile));
            AssertEqualIgnoreCrlf(@"
test1
test2
partial 1:
partial 2:
test1
test2
", File.ReadAllText(outputFile));
        }
コード例 #7
0
        public void TestLiquidTemplateProcessSingleTemplateWithNoScriptWithIncludeShouldWork()
        {
            // 1. Prepare template
            var    templateName = "NoScriptWithInclude.liquid";
            string template     = @"
{% for item in model -%}
{{ item.name }}
{% endfor -%}
{% include partial1 -%}
";
            string partial1     = @"partial 1:
{% include partial2 -%}";
            string partial2     = @"partial 2:
{% for item in model -%}
{{ item.name }}
{% endfor -%}
";
            var    model        = new
            {
                model = new[]
                {
                    new { name = "test1" },
                    new { name = "test2" },
                }
            };
            var modelFileName = Path.Combine(_inputFolder, "TestLiquidTemplateProcessor_NoScriptWithPartial.yml");
            var item          = new InternalManifestItem
            {
                DocumentType         = string.Empty,
                Key                  = modelFileName,
                FileWithoutExtension = Path.ChangeExtension(modelFileName, null),
                ResourceFile         = modelFileName,
                LocalPathFromRoot    = modelFileName,
            };

            ProcessTemplate(
                templateName,
                null,
                new[] { item },
                model,
                _outputFolder,
                Tuple.Create("default.liquid", template),
                Tuple.Create("_partial1.liquid", partial1),
                Tuple.Create("_partial2.liquid", partial2));

            var outputFile = Path.Combine(_outputFolder, Path.ChangeExtension(modelFileName, string.Empty));

            Assert.True(File.Exists(outputFile));
            AssertEqualIgnoreCrlf(@"
test1
test2
partial 1:
partial 2:
test1
test2
", File.ReadAllText(outputFile));
        }
コード例 #8
0
        public SystemMetadata Generate(InternalManifestItem item)
        {
            var attrs = new SystemMetadata
            {
                Language = Constants.DefaultLanguage,
            };

            string key = GetFileKey(item.Key);
            var file = (TypeForwardedToRelativePath)(item.FileWithoutExtension + item.Extension);

            attrs.RelativePathToRoot = (TypeForwardedToRelativePath.Empty).MakeRelativeTo(file);
            var fileWithoutWorkingFolder = file.RemoveWorkingFolder();
            attrs.Path = fileWithoutWorkingFolder;

            // 1. Root Toc is always in the top directory of output folder
            var rootToc = _toc.FirstOrDefault();
            if (rootToc != null)
            {
                var rootTocPath = rootToc.File.RemoveWorkingFolder();
                if (rootTocPath.SubdirectoryCount == 0)
                {
                    attrs.RootTocPath = rootTocPath;
                    var rootTocRelativePath = rootTocPath.MakeRelativeTo(file);
                    attrs.RelativePathToRootToc = rootTocRelativePath;
                    attrs.RootTocKey = rootToc.Key;
                    Logger.LogVerbose($"Root TOC file {rootTocPath} is found.");
                }
                else
                {
                    Logger.LogVerbose($"Root TOC file from output folder is not found, the toppest TOC file is {rootTocPath}");
                }
            }

            // 2. The algorithm of toc current article belongs to:
            //    a. If toc can be found in TocMap, return that toc
            //    b. Elsewise, get the nearest toc, **nearest** means nearest toc in **OUTPUT** folder
            var parentTocFiles = _context.GetTocFileKeySet(key)?.Select(s => new FileInfo(s, (TypeForwardedToRelativePath)_context.GetFilePath(s)));
            var parentToc = GetNearestToc(parentTocFiles, file) ?? GetDefaultToc(key);

            if (parentToc != null)
            {
                var parentTocPath = parentToc.File.RemoveWorkingFolder();
                attrs.TocPath = parentTocPath;
                var tocRelativePath = parentTocPath.MakeRelativeTo(file);
                attrs.RelativePathToToc = tocRelativePath;
                attrs.TocKey = parentToc.Key;
                Logger.LogVerbose($"TOC file {parentTocPath} is found for {item.LocalPathFromRoot}.");
            }
            else
            {
                Logger.LogVerbose($"TOC file for {item.LocalPathFromRoot} is not found.");
            }

            return attrs;
        }
コード例 #9
0
        public void TestLiquidTemplateProcessSingleTemplateWithDependenciesShouldWork()
        {
            var templateName = "WithIncludes.liquid";

            string template = @"
{% ref reference1.html -%}
{% ref reference2.html -%}
{% for item in model -%}
{{ item.name }}
{% endfor -%}
";
            string script   = @"
exports.transform = function (model){
    model.model.push({name:'test2'});
    return model;
}";

            var model = new
            {
                model = new List <object>
                {
                    new { name = "test1" },
                }
            };

            var    modelFileName = Path.Combine(_inputFolder, "TestLiquidTemplateProcessor_WithIncludes.yml");
            string inputFolder   = null;
            var    item          = new InternalManifestItem
            {
                FileWithoutExtension = Path.ChangeExtension(modelFileName, null),
                DocumentType         = string.Empty,
                Key = modelFileName,
                LocalPathFromRoot = modelFileName,
            };

            ProcessTemplate(templateName, inputFolder, new[] { item }, model, _outputFolder,
                            Tuple.Create("default.html.liquid", template),
                            Tuple.Create("default.html.js", script),
                            Tuple.Create("reference1.html", string.Empty),
                            Tuple.Create("reference2.html", string.Empty)
                            );
            var outputFilePath = Path.Combine(_outputFolder, Path.ChangeExtension(modelFileName, "html"));

            Assert.True(File.Exists(outputFilePath));
            Assert.True(File.Exists(Path.Combine(_outputFolder, "reference1.html")));
            Assert.True(File.Exists(Path.Combine(_outputFolder, "reference2.html")));
            AssertEqualIgnoreCrlf(@"
test1
test2
", File.ReadAllText(outputFilePath));
        }
コード例 #10
0
        public void TestMustacheTemplateProcessInvalidTemplateShouldFail()
        {
            var    templateName  = "InvalidTemplate.html";
            string inputFolder   = null;
            var    modelFileName = Path.Combine(_inputFolder, "TestTemplateProcessor_InvalidTemplate.yml");
            var    item          = new InternalManifestItem {
                FileWithoutExtension = Path.ChangeExtension(modelFileName, null), DocumentType = string.Empty, Key = modelFileName
            };

            ProcessTemplate(templateName, inputFolder, new[] { item }, new object(), _outputFolder,
                            Tuple.Create("default.invalidtmpl", string.Empty),
                            Tuple.Create("default.js", string.Empty),
                            Tuple.Create("reference1.html", string.Empty),
                            Tuple.Create("reference2.html", string.Empty)
                            );
        }
コード例 #11
0
        public void TestMustacheTemplateProcessSingleTemplateWithIncludesShouldWork()
        {
            var templateName = "WithIncludes.html";

            string template = @"
{{ !include('reference1.html') }}
{{ !include('reference2.html') }}
{{#model}}
{{name}}
{{/model}}
";
            string script   = @"
exports.transform = function (model){
    model.model.push({name:'test2'});
    return model;
}";

            var model = new
            {
                model = new List <object>
                {
                    new { name = "test1" },
                }
            };

            var    modelFileName = Path.Combine(_inputFolder, "TestTemplateProcessor_WithIncludes.yml");
            string inputFolder   = null;
            var    item          = new InternalManifestItem {
                FileWithoutExtension = Path.ChangeExtension(modelFileName, null), DocumentType = string.Empty, Key = modelFileName
            };

            ProcessTemplate(templateName, inputFolder, new[] { item }, model, _outputFolder,
                            Tuple.Create("default.html.tmpl", template),
                            Tuple.Create("default.html.js", script),
                            Tuple.Create("reference1.html", string.Empty),
                            Tuple.Create("reference2.html", string.Empty)
                            );
            var outputFilePath = Path.Combine(_outputFolder, Path.ChangeExtension(modelFileName, "html"));

            Assert.True(File.Exists(outputFilePath));
            Assert.True(File.Exists(Path.Combine(_outputFolder, "reference1.html")));
            Assert.True(File.Exists(Path.Combine(_outputFolder, "reference2.html")));
            Assert.Equal(@"
test1
test2
", File.ReadAllText(outputFilePath));
        }
コード例 #12
0
ファイル: TemplateBundle.cs プロジェクト: dotnet/docfx
        private IEnumerable<TransformModelOptions> GetOptionsForEachTemplate(InternalManifestItem item, IDocumentBuildContext context)
        {
            if (item == null)
            {
                yield break;
            }

            foreach (var template in Templates)
            {
                if (template.ContainsGetOptions)
                {
                    var options = template.GetOptions(item.Model.Content);
                    if (options != null)
                    {
                        yield return options;
                    }
                }
            }
        }
コード例 #13
0
        private ManifestItem Process(string documentType, string fileName, object content, XRefSpec spec)
        {
            var reader  = new LocalFileResourceReader(_templateFolder);
            var context = new DocumentBuildContext(_outputFolder);

            context.RegisterInternalXrefSpec(spec);
            var processor = new TemplateProcessor(reader, context, 64);
            var inputItem = new InternalManifestItem
            {
                DocumentType         = documentType,
                Extension            = "html",
                FileWithoutExtension = Path.GetFullPath(Path.Combine(_outputFolder, Path.GetFileNameWithoutExtension(fileName))),
                LocalPathFromRoot    = fileName,
                Model = new ModelWithCache(content),
            };

            return(processor.Process(new List <InternalManifestItem> {
                inputItem
            }, new ApplyTemplateSettings(_inputFolder, _outputFolder))[0]);
        }
コード例 #14
0
        public void TestMustacheTemplateWithScriptWithLongStringInModelShouldWork()
        {
            // https://github.com/sebastienros/jint/issues/357

            var    templateName    = "TemplateFolder.html";
            string defaultTemplate = @"{{name}}";
            var    name            = "this is a looooooooooooooooooooooooooooooooooooog name";
            var    longName        = string.Concat(Enumerable.Repeat(name, 20000));
            string script          = @"
exports.transform = function (model){
    return {
        name: JSON.stringify(model)
    };
}";

            var model = new
            {
                model = new
                {
                    name = longName,
                }
            };

            string inputFolder = null;
            var    item1       = new InternalManifestItem
            {
                FileWithoutExtension = "TestMustacheTemplateWithScriptWithLongStringInModelShouldWork",
                Key               = "x.yml",
                DocumentType      = "Conceptual",
                LocalPathFromRoot = "TestMustacheTemplateWithScriptWithLongStringInModelShouldWork.md",
            };

            ProcessTemplate(templateName, inputFolder, new[] { item1 }, model, _outputFolder,
                            Tuple.Create("default.html.tmpl", defaultTemplate),
                            Tuple.Create("default.html.js", script)
                            );
            var outputFilePath1 = Path.Combine(_outputFolder, "TestMustacheTemplateWithScriptWithLongStringInModelShouldWork.html");

            Assert.True(File.Exists(outputFilePath1));
            Assert.Equal($"{{&quot;model&quot;:{{&quot;name&quot;:&quot;{longName}&quot;}},&quot;__global&quot;:{{}}}}", File.ReadAllText(outputFilePath1));
        }
コード例 #15
0
        public void JsRegexShouldNotShareStatusAmongFunctions()
        {
            // https://github.com/sebastienros/jint/issues/364

            var    templateName    = "TemplateFolder.html";
            string defaultTemplate = @"{{result1}},{{result2}}";
            string script          = @"
exports.transform = function (model){
    var url = 'https://www.example.com';
    var result1 = isAbsolutePath(url);
    var result2 = isAbsolutePath(url);

    function isAbsolutePath(path) {
        return /^(\w+:)?\/\//g.test(path);
    }

    return {
        result1: result1,
        result2: result2
    };
}";

            var model = new object();
            var item1 = new InternalManifestItem
            {
                FileWithoutExtension = "file",
                Key               = "x.yml",
                DocumentType      = "Conceptual",
                LocalPathFromRoot = "file.md",
            };

            ProcessTemplate(templateName, null, new[] { item1 }, model, _outputFolder,
                            Tuple.Create("default.html.tmpl", defaultTemplate),
                            Tuple.Create("default.html.js", script)
                            );
            var outputFilePath1 = Path.Combine(_outputFolder, "file.html");

            Assert.True(File.Exists(outputFilePath1));
            Assert.Equal("True,True", File.ReadAllText(outputFilePath1));
        }
コード例 #16
0
        public void TestLiquidTemplateProcessSingleTemplateWithDependenciesShouldWork()
        {
            var templateName = "WithIncludes.liquid";

            string template = @"
{% ref reference1.html -%}
{% ref reference2.html -%}
{% for item in model -%}
{{ item.name }}
{% endfor -%}
";
            string script = @"
exports.transform = function (model){
    model.model.push({name:'test2'});
    return model;
}";

            var model = new
            {
                model = new List<object>
               {
                   new {name = "test1"},
               }
            };

            var modelFileName = Path.Combine(_inputFolder, "TestLiquidTemplateProcessor_WithIncludes.yml");
            string inputFolder = null;
            var item = new InternalManifestItem
            {
                FileWithoutExtension = Path.ChangeExtension(modelFileName, null),
                DocumentType = string.Empty,
                Key = modelFileName,
                LocalPathFromRoot = modelFileName,
            };
            ProcessTemplate(templateName, inputFolder, new[] { item }, model, _outputFolder,
                Tuple.Create("default.html.liquid", template),
                Tuple.Create("default.html.js", script),
                Tuple.Create("reference1.html", string.Empty),
                Tuple.Create("reference2.html", string.Empty)
                );
            var outputFilePath = Path.Combine(_outputFolder, Path.ChangeExtension(modelFileName, "html"));
            Assert.True(File.Exists(outputFilePath));
            Assert.True(File.Exists(Path.Combine(_outputFolder, "reference1.html")));
            Assert.True(File.Exists(Path.Combine(_outputFolder, "reference2.html")));
            Assert.Equal(@"
test1
test2
", File.ReadAllText(outputFilePath));
        }
コード例 #17
0
        public void TestLiquidTemplateProcessTemplateFolderWithDifferentTypeShouldWork()
        {
            var templateName = "TemplateFolder.liquid";
            string defaultTemplate = @"
default:
{% for item in model -%}
{{ item.name }}
{% endfor -%}
";
            string conceptualTemplate = @"
conceptual:
{% for item in model -%}
{{ item.name }}
{% endfor -%}
";
            string script = @"
exports.transform = function (model){
    model.model.push({name:'test2'});
    return model;
}";

            var model = new
            {
                model = new List<object>
               {
                   new {name = "test1"},
               },
                another = new Dictionary<string, object>
                {
                    ["key1"] = new { name = "test3" },
                    ["key2"] = new { name = "test4" }
                }
            };

            string inputFolder = null;
            var item1 = new InternalManifestItem
            {
                FileWithoutExtension = "TestLiquidTemplateProcessor_TemplateFolderWithDifferentType1",
                Key = "x.yml",
                DocumentType = "Conceptual",
                LocalPathFromRoot = "TestLiquidTemplateProcessor_TemplateFolderWithDifferentType1.md",
            };
            var item2 = new InternalManifestItem
            {
                DocumentType = string.Empty,
                FileWithoutExtension = "TestLiquidTemplateProcessor_TemplateFolderWithDifferentType2",
                Key = "y.yml",
                LocalPathFromRoot = "TestLiquidTemplateProcessor_TemplateFolderWithDifferentType2.md",
            };
            ProcessTemplate(templateName, inputFolder, new[] { item1, item2 }, model, _outputFolder,
                Tuple.Create("default.html.liquid", defaultTemplate),
                Tuple.Create($"{templateName}/conceptual.md.liquid", conceptualTemplate),
                Tuple.Create("default.html.js", script),
                Tuple.Create("conceptual.md.js", script)
                );
            var outputFilePath1 = Path.Combine(_outputFolder, "TestLiquidTemplateProcessor_TemplateFolderWithDifferentType1.md");
            Assert.True(File.Exists(outputFilePath1));
            Assert.Equal(@"
conceptual:
test1
test2
", File.ReadAllText(outputFilePath1));
            var outputFilePath2 = Path.Combine(_outputFolder, "TestLiquidTemplateProcessor_TemplateFolderWithDifferentType2.html");
            Assert.True(File.Exists(outputFilePath2));
            Assert.Equal(@"
default:
test1
test2
", File.ReadAllText(outputFilePath2));
        }
コード例 #18
0
        public void TestMustacheTemplateProcessSingleTemplateWithNoScriptShouldWork()
        {
            // 1. Prepare template
            var templateName = "NoScript";
            string template = @"
{{#model}}
name1={{name1}},
name2={{name2}};
{{/model}}
";
            var model = new
            {
                model = new object[]
               {
                   new {name1 = "test1"},
                   new {name2 = "test2"},
               }
            };
            var modelFileName = Path.Combine(_inputFolder, "TestTemplateProcessor_NoScript.yml");
            var item = new InternalManifestItem
            {
                DocumentType = string.Empty,
                Key = modelFileName,
                FileWithoutExtension = Path.ChangeExtension(modelFileName, null),
                ResourceFile = modelFileName,
                LocalPathFromRoot = modelFileName,
            };
            ProcessTemplate(templateName, null, new[] { item }, model, _outputFolder, Tuple.Create("default.tmpl", template));

            var outputFile = Path.Combine(_outputFolder, Path.ChangeExtension(modelFileName, string.Empty));
            Assert.True(File.Exists(outputFile));
            Assert.Equal(@"
name1=test1,
name2=;
name1=,
name2=test2;
", File.ReadAllText(outputFile));
        }
コード例 #19
0
        public void TestMustacheTemplateWithMasterPageShouldWork()
        {
            // 1. Prepare template
            var    templateName = "Subfolder/WithMasterPage";
            string template     = @"
{{!master('_layout/master.html')}}
{{!master(' _layout/invalid1.html ')}}
{{#model}}
{{name}}
{{/model}}
{{>partial1}}
{{!master( _layout/invalid2.html )}}
";
            string partial1     = @"partial 1:
{{>partial2}}";
            string partial2     = @"partial 2:
{{#model}}
{{name}}
{{/model}}
";

            string master = @"
{{ !include('reference1.html') }}
Hello Master
{{!body}}
Hello Body
{{!body}}
";
            var    model  = new
            {
                model = new[]
                {
                    new { name = "test1" },
                    new { name = "test2" },
                }
            };
            var modelFileName = Path.Combine(_inputFolder, "TestTemplateProcessor_WithMasterPage.yml");
            var item          = new InternalManifestItem
            {
                DocumentType         = string.Empty,
                Key                  = modelFileName,
                FileWithoutExtension = Path.ChangeExtension(modelFileName, null),
                ResourceFile         = modelFileName,
                LocalPathFromRoot    = modelFileName,
            };

            ProcessTemplate(
                templateName,
                null,
                new[] { item },
                model,
                _outputFolder,
                Tuple.Create("default.tmpl", template),
                Tuple.Create("_layout/master.html", master),
                Tuple.Create("reference1.html", string.Empty),
                Tuple.Create("partial1.tmpl.partial", partial1),
                Tuple.Create("partial2.tmpl.partial", partial2));

            var outputFile = Path.Combine(_outputFolder, Path.ChangeExtension(modelFileName, string.Empty));

            Assert.True(File.Exists(Path.Combine(_outputFolder, "reference1.html")));
            Assert.True(File.Exists(outputFile));
            AssertEqualIgnoreCrlf(@"
Hello Master

test1
test2
partial 1:
partial 2:
test1
test2
Hello Body

test1
test2
partial 1:
partial 2:
test1
test2
", File.ReadAllText(outputFile));
        }
コード例 #20
0
        /// <summary>
        /// Must guarantee thread safety
        /// </summary>
        /// <param name="item"></param>
        /// <returns></returns>
        internal ManifestItem Transform(InternalManifestItem item)
        {
            if (item.Model == null || item.Model.Content == null) throw new ArgumentNullException("Content for item.Model should not be null!");
            var model = ConvertObjectToDictionary(item.Model.Content);
            model = AppendGlobalMetadata(model);
            if (_settings.Options.HasFlag(ApplyTemplateOptions.ExportRawModel))
            {
                ExportModel(model, item.FileWithoutExtension, _settings.RawModelExportSettings);
            }

            var manifestItem = new ManifestItem
            {
                DocumentType = item.DocumentType,
                SourceRelativePath = item.LocalPathFromRoot,
                OutputFiles = new Dictionary<string, OutputFileInfo>(),
                Metadata = item.Metadata,
            };
            var outputDirectory = _settings.OutputFolder ?? Directory.GetCurrentDirectory();

            // 1. process resource
            if (item.ResourceFile != null)
            {
                // Resource file has already been processed in its plugin
                manifestItem.OutputFiles.Add("resource", new OutputFileInfo
                {
                    RelativePath = item.ResourceFile,
                    LinkToPath = null,
                    Hash = null
                });
            }

            // 2. process model
            var templateBundle = _templateCollection[item.DocumentType];
            if (templateBundle == null)
            {
                return manifestItem;
            }

            HashSet<string> missingUids = new HashSet<string>();

            // Must convert to JObject first as we leverage JsonProperty as the property name for the model
            foreach (var template in templateBundle.Templates)
            {
                if (!template.ContainsTemplateRenderer)
                {
                    continue;
                }
                try
                {
                    var extension = template.Extension;
                    string outputFile = item.FileWithoutExtension + extension;
                    string outputPath = Path.Combine(outputDirectory, outputFile);
                    var dir = Path.GetDirectoryName(outputPath);
                    if (!string.IsNullOrEmpty(dir)) Directory.CreateDirectory(dir);
                    object viewModel = null;
                    try
                    {
                        viewModel = template.TransformModel(model);
                    }
                    catch (Exception e)
                    {
                        // save raw model for further investigation:
                        var exportSettings = ApplyTemplateSettings.RawModelExportSettingsForDebug;
                        var rawModelPath = ExportModel(model, item.FileWithoutExtension, exportSettings);
                        var message = $"Error transforming model \"{rawModelPath}\" generated from \"{item.LocalPathFromRoot}\" using \"{template.ScriptName}\": {e.Message}";
                        Logger.LogError(message);
                        throw new DocumentException(message, e);
                    }

                    string result;
                    try
                    {
                        result = template.Transform(viewModel);
                    }
                    catch (Exception e)
                    {
                        // save view model for further investigation:
                        var exportSettings = ApplyTemplateSettings.ViewModelExportSettingsForDebug;
                        var viewModelPath = ExportModel(viewModel, outputFile, exportSettings);
                        var message = $"Error applying template \"{template.Name}\" to view model \"{viewModelPath}\" generated from \"{item.LocalPathFromRoot}\": {e.Message}";
                        Logger.LogError(message);
                        throw new DocumentException(message, e);
                    }

                    if (_settings.Options.HasFlag(ApplyTemplateOptions.ExportViewModel))
                    {
                        ExportModel(viewModel, outputFile, _settings.ViewModelExportSettings);
                    }

                    if (_settings.Options.HasFlag(ApplyTemplateOptions.TransformDocument))
                    {
                        if (string.IsNullOrWhiteSpace(result))
                        {
                            // TODO: WHAT to do if is transformed to empty string? STILL creat empty file?
                            var exportSettings = ApplyTemplateSettings.ViewModelExportSettingsForDebug;
                            var viewModelPath = ExportModel(viewModel, outputFile, exportSettings);
                            Logger.LogWarning($"Model \"{viewModelPath}\" is transformed to empty string with template \"{template.Name}\"");
                        }
                        TransformDocument(result ?? string.Empty, extension, _context, outputPath, outputFile, missingUids, manifestItem);
                        Logger.LogDiagnostic($"Transformed model \"{item.LocalPathFromRoot}\" to \"{outputPath}\".");
                    }
                }
                catch (PathTooLongException e)
                {
                    var message = $"Error processing {item.LocalPathFromRoot}: {e.Message}";
                    throw new PathTooLongException(message, e);
                }

            }

            if (missingUids.Count > 0)
            {
                var uids = string.Join(", ", missingUids.Select(s => $"\"{s}\""));
                Logger.LogWarning($"Invalid cross reference {uids}.", null, item.LocalPathFromRoot);
            }

            return manifestItem;
        }
コード例 #21
0
ファイル: TemplateBundle.cs プロジェクト: dotnet/docfx
 internal TransformModelOptions GetOptions(InternalManifestItem item, IDocumentBuildContext context)
 {
     return MergeOptions(GetOptionsForEachTemplate(item, context));
 }
コード例 #22
0
        public void TestLiquidTemplateProcessSingleTemplateWithNoScriptWithIncludeShouldWork()
        {
            // 1. Prepare template
            var templateName = "NoScriptWithInclude.liquid";
            string template = @"
{% for item in model -%}
{{ item.name }}
{% endfor -%}
{% include partial1 -%}
";
            string partial1 = @"partial 1:
{% include partial2 -%}";
            string partial2 = @"partial 2:
{% for item in model -%}
{{ item.name }}
{% endfor -%}
";
            var model = new
            {
                model = new[]
               {
                   new {name = "test1"},
                   new {name = "test2"},
               }
            };
            var modelFileName = Path.Combine(_inputFolder, "TestLiquidTemplateProcessor_NoScriptWithPartial.yml");
            var item = new InternalManifestItem
            {
                DocumentType = string.Empty,
                Key = modelFileName,
                FileWithoutExtension = Path.ChangeExtension(modelFileName, null),
                ResourceFile = modelFileName,
                LocalPathFromRoot = modelFileName,
            };
            ProcessTemplate(
                templateName,
                null,
                new[] { item },
                model,
                _outputFolder,
                Tuple.Create("default.liquid", template),
                Tuple.Create("_partial1.liquid", partial1),
                Tuple.Create("_partial2.liquid", partial2));

            var outputFile = Path.Combine(_outputFolder, Path.ChangeExtension(modelFileName, string.Empty));
            Assert.True(File.Exists(outputFile));
            Assert.Equal(@"
test1
test2
partial 1:
partial 2:
test1
test2
", File.ReadAllText(outputFile));
        }
コード例 #23
0
        public void TestLiquidTemplateWithMasterPageShouldWork()
        {
            // 1. Prepare template
            var    templateName = "Subfolder/LiquidWithMasterPage";
            string template     = @"
{% master _layout/master.html -%}
{% master _layout/master.html -%}
{% for item in model -%}
{{ item.name }}
{% endfor -%}
{% include partial1 -%}
";
            string partial1     = @"partial 1:
{% include partial2 -%}";
            string partial2     = @"partial 2:
{% for item in model -%}
{{ item.name }}
{% endfor -%}
";

            string master = @"
{% ref reference1.html -%}
Hello Master
{% include partial1 -%}
{%- body %}
";
            var    model  = new
            {
                model = new[]
                {
                    new { name = "test1" },
                    new { name = "test2" },
                }
            };
            var modelFileName = Path.Combine(_inputFolder, "TestTemplateProcessor_LiquidWithMasterPage.yml");
            var item          = new InternalManifestItem
            {
                DocumentType         = string.Empty,
                Key                  = modelFileName,
                FileWithoutExtension = Path.ChangeExtension(modelFileName, null),
                ResourceFile         = modelFileName,
                LocalPathFromRoot    = modelFileName,
            };

            ProcessTemplate(
                templateName,
                null,
                new[] { item },
                model,
                _outputFolder,
                Tuple.Create("default.liquid", template),
                Tuple.Create("_layout/master.html", master),
                Tuple.Create("reference1.html", string.Empty),
                Tuple.Create("_partial1.liquid", partial1),
                Tuple.Create("_partial2.liquid", partial2));

            var outputFile = Path.Combine(_outputFolder, Path.ChangeExtension(modelFileName, string.Empty));

            Assert.True(File.Exists(Path.Combine(_outputFolder, "reference1.html")));
            Assert.True(File.Exists(outputFile));
            AssertEqualIgnoreCrlf(@"
Hello Master
partial 1:
partial 2:
test1
test2

test1
test2
partial 1:
partial 2:
test1
test2
", File.ReadAllText(outputFile));
        }
コード例 #24
0
ファイル: SingleDocumentBuilder.cs プロジェクト: dotnet/docfx
 public ManifestItemWithContext(InternalManifestItem item, FileModel model, IDocumentProcessor processor, TemplateBundle bundle)
 {
     Item = item;
     FileModel = model;
     Processor = processor;
     TemplateBundle = bundle;
 }
コード例 #25
0
        public void TestLiquidTemplateProcessTemplateFolderWithDifferentTypeShouldWork()
        {
            var    templateName       = "TemplateFolder.liquid";
            string defaultTemplate    = @"
default:
{% for item in model -%}
{{ item.name }}
{% endfor -%}
";
            string conceptualTemplate = @"
conceptual:
{% for item in model -%}
{{ item.name }}
{% endfor -%}
";
            string script             = @"
exports.transform = function (model){
    model.model.push({name:'test2'});
    return model;
}";

            var model = new
            {
                model = new List <object>
                {
                    new { name = "test1" },
                },
                another = new Dictionary <string, object>
                {
                    ["key1"] = new { name = "test3" },
                    ["key2"] = new { name = "test4" }
                }
            };

            string inputFolder = null;
            var    item1       = new InternalManifestItem
            {
                FileWithoutExtension = "TestLiquidTemplateProcessor_TemplateFolderWithDifferentType1",
                Key               = "x.yml",
                DocumentType      = "Conceptual",
                LocalPathFromRoot = "TestLiquidTemplateProcessor_TemplateFolderWithDifferentType1.md",
            };
            var item2 = new InternalManifestItem
            {
                DocumentType         = string.Empty,
                FileWithoutExtension = "TestLiquidTemplateProcessor_TemplateFolderWithDifferentType2",
                Key = "y.yml",
                LocalPathFromRoot = "TestLiquidTemplateProcessor_TemplateFolderWithDifferentType2.md",
            };

            ProcessTemplate(templateName, inputFolder, new[] { item1, item2 }, model, _outputFolder,
                            Tuple.Create("default.html.liquid", defaultTemplate),
                            Tuple.Create("conceptual.md.liquid", conceptualTemplate),
                            Tuple.Create("default.html.js", script),
                            Tuple.Create("conceptual.md.js", script)
                            );
            var outputFilePath1 = Path.Combine(_outputFolder, "TestLiquidTemplateProcessor_TemplateFolderWithDifferentType1.md");

            Assert.True(File.Exists(outputFilePath1));
            AssertEqualIgnoreCrlf(@"
conceptual:
test1
test2
", File.ReadAllText(outputFilePath1));
            var outputFilePath2 = Path.Combine(_outputFolder, "TestLiquidTemplateProcessor_TemplateFolderWithDifferentType2.html");

            Assert.True(File.Exists(outputFilePath2));
            AssertEqualIgnoreCrlf(@"
default:
test1
test2
", File.ReadAllText(outputFilePath2));
        }
コード例 #26
0
 public void TestMustacheTemplateProcessInvalidTemplateShouldFail()
 {
     var templateName = "InvalidTemplate.html";
     string inputFolder = null;
     var modelFileName = Path.Combine(_inputFolder, "TestTemplateProcessor_InvalidTemplate.yml");
     var item = new InternalManifestItem
     {
         FileWithoutExtension = Path.ChangeExtension(modelFileName, null),
         DocumentType = string.Empty,
         Key = modelFileName,
         LocalPathFromRoot = modelFileName,
     };
     ProcessTemplate(templateName, inputFolder, new[] { item }, new object(), _outputFolder,
         Tuple.Create("default.invalidtmpl", string.Empty),
         Tuple.Create("default.js", string.Empty),
         Tuple.Create("reference1.html", string.Empty),
         Tuple.Create("reference2.html", string.Empty)
         );
 }