Beispiel #1
0
        public async Task <string> RenderAsync(string template, TemplateVars variables)
        {
            Guard.NotNull(variables, nameof(variables));

            if (SquidexTemplate.TryParse(template, out var parsed, out var errors))
            {
                var context = new TemplateContext();

                foreach (var extension in extensions)
                {
                    extension.BeforeRun(context);
                }

                foreach (var(key, value) in variables)
                {
                    context.MemberAccessStrategy.Register(value.GetType());

                    context.SetValue(key, value);
                }

                var result = await parsed.RenderAsync(context);

                return(result);
            }

            throw new TemplateParseException(template, errors);
        }
        public async Task Should_resolve_text_from_event(string encoding)
        {
            var @event = new EnrichedAssetEvent
            {
                Id          = DomainId.NewGuid(),
                FileVersion = 0,
                FileSize    = 100,
                AppId       = appId
            };

            SetupText(@event.ToRef(), Encode(encoding, "hello+assets"));

            var vars = new TemplateVars
            {
                ["event"] = @event
            };

            var template = $@"
                Text: {{{{ event | assetText: '{encoding}' }}}}
            ";

            var expected = $@"
                Text: hello+assets
            ";

            var result = await sut.RenderAsync(template, vars);

            Assert.Equal(Cleanup(expected), Cleanup(result));
        }
        public async Task Should_resolve_asset_text_from_event()
        {
            var @event = new EnrichedAssetEvent
            {
                Id          = DomainId.NewGuid(),
                FileVersion = 0,
                FileSize    = 100,
                AppId       = appId
            };

            SetupText(@event.Id, Encoding.UTF8.GetBytes("Hello Asset"));

            var vars = new TemplateVars
            {
                ["event"] = @event
            };

            var template = @"
                Text: {{ event | assetText }}
            ";

            var expected = $@"
                Text: Hello Asset
            ";

            var result = await sut.RenderAsync(template, vars);

            Assert.Equal(Cleanup(expected), Cleanup(result));
        }
        public async Task Should_resolve_blur_hash_from_event()
        {
            var @event = new EnrichedAssetEvent
            {
                Id          = DomainId.NewGuid(),
                AssetType   = AssetType.Image,
                FileVersion = 0,
                FileSize    = 100,
                AppId       = appId
            };

            SetupBlurHash(@event.ToRef(), "Hash");

            var vars = new TemplateVars
            {
                ["event"] = @event
            };

            var template = @"
                Text: {{ event | assetBlurHash }}
            ";

            var expected = $@"
                Text: Hash
            ";

            var result = await sut.RenderAsync(template, vars);

            Assert.Equal(Cleanup(expected), Cleanup(result));
        }
        public async Task Should_not_resolve_asset_text_from_event_if_too_big()
        {
            var @event = new EnrichedAssetEvent
            {
                Id          = DomainId.NewGuid(),
                FileVersion = 0,
                FileSize    = 1_000_000,
                AppId       = appId
            };

            var vars = new TemplateVars
            {
                ["event"] = @event
            };

            var template = @"
                Text: {{ event | assetText }}
            ";

            var expected = $@"
                Text: ErrorTooBig
            ";

            var result = await sut.RenderAsync(template, vars);

            Assert.Equal(Cleanup(expected), Cleanup(result));

            A.CallTo(() => assetFileStore.DownloadAsync(A <DomainId> ._, A <DomainId> ._, A <long> ._, null, A <Stream> ._, A <BytesRange> ._, A <CancellationToken> ._))
            .MustNotHaveHappened();
        }
        private (TemplateVars, IAssetEntity) SetupAssetVars(int fileSize = 100)
        {
            var assetId = DomainId.NewGuid();
            var asset   = CreateAsset(assetId, 1, fileSize);

            var @event = new EnrichedContentEvent
            {
                Data =
                    new ContentData()
                    .AddField("assets",
                              new ContentFieldData()
                              .AddInvariant(JsonValue.Array(assetId))),
                AppId = appId
            };

            A.CallTo(() => assetQuery.FindAsync(A <Context> ._, assetId, EtagVersion.Any, A <CancellationToken> ._))
            .Returns(asset);

            SetupText(@event.Id, Encoding.UTF8.GetBytes("Hello Asset"));

            var vars = new TemplateVars
            {
                ["event"] = @event
            };

            return(vars, asset);
        }
        private (TemplateVars, IAssetEntity[]) SetupAssetsVars(int fileSize = 100)
        {
            var assetId1 = DomainId.NewGuid();
            var asset1   = CreateAsset(assetId1, 1, fileSize);
            var assetId2 = DomainId.NewGuid();
            var asset2   = CreateAsset(assetId2, 2, fileSize);

            var @event = new EnrichedContentEvent
            {
                Data =
                    new ContentData()
                    .AddField("assets",
                              new ContentFieldData()
                              .AddInvariant(JsonValue.Array(assetId1, assetId2))),
                AppId = appId
            };

            A.CallTo(() => assetQuery.FindAsync(A <Context> ._, assetId1, EtagVersion.Any, A <CancellationToken> ._))
            .Returns(asset1);

            A.CallTo(() => assetQuery.FindAsync(A <Context> ._, assetId2, EtagVersion.Any, A <CancellationToken> ._))
            .Returns(asset2);

            var vars = new TemplateVars
            {
                ["event"] = @event
            };

            return(vars, new[] { asset1, asset2 });
        }
Beispiel #8
0
 public void AddTemplateVar(string name, object data)
 {
     if (TemplateVars == null)
     {
         TemplateVars = new List <TemplateVar>();
     }
     TemplateVars.Add(new TemplateVar()
     {
         Name = name, Data = data
     });
 }
 public TableScaffolder(
     TemplateVars templateVars,
     ITemplateProvider templateProvider,
     IFilePersister filePersister,
     ProjectItem projectItem,
     ILogger logger)
 {
     this.templateVars = templateVars;
     this.templateProvider = templateProvider;
     this.filePersister = filePersister;
     this.projectItem = projectItem;
     this.logger = logger;
 }
Beispiel #10
0
 public TableScaffolder(
     TemplateVars templateVars,
     ITemplateProvider templateProvider,
     IFilePersister filePersister,
     ProjectItem projectItem,
     ILogger logger)
 {
     this.templateVars     = templateVars;
     this.templateProvider = templateProvider;
     this.filePersister    = filePersister;
     this.projectItem      = projectItem;
     this.logger           = logger;
 }
Beispiel #11
0
        public async ValueTask <string?> FormatAsync(string text, EnrichedEvent @event)
        {
            if (string.IsNullOrWhiteSpace(text))
            {
                return(text);
            }

            if (TryGetTemplate(text.Trim(), out var template))
            {
                var vars = new TemplateVars
                {
                    ["event"] = @event
                };

                return(await templateEngine.RenderAsync(template, vars));
            }

            if (TryGetScript(text.Trim(), out var script))
            {
                // Script vars are just wrappers over dictionaries for better performance.
                var vars = new EventScriptVars
                {
                    Event   = @event,
                    AppId   = @event.AppId.Id,
                    AppName = @event.AppId.Name,
                    User    = Admin()
                };

                var result = (await scriptEngine.ExecuteAsync(vars, script)).ToString();

                if (result == "undefined")
                {
                    return(GlobalFallback);
                }

                return(result);
            }

            var parts = BuildParts(text, @event);

            if (parts.Any(x => !x.Var.IsCompleted))
            {
                await ValueTaskEx.WhenAll(parts.Select(x => x.Var));
            }

            return(CombineParts(text, parts));
        }
Beispiel #12
0
        public override void AcceptContent(RCToken token)
        {
            TemplateVars template     = _templates.Peek();
            int          firstNewline = token.Text.IndexOfAny(CRLF);

            if (firstNewline > -1)
            {
                template._multilineTemplate = true;
            }
            // I want it to be AS IF we saw something like {:"foo bar with newlines"}
            // AcceptEvaluator (new RCToken (":", RCTokenType.Evaluator, token.Start,
            // token.Index));
            // soo...
            _variable  = "";
            _evaluator = RCEvaluator.Let;
            _result    = new RCString(token.Text);
        }
Beispiel #13
0
        public async ValueTask <string?> FormatAsync(string text, EnrichedEvent @event)
        {
            if (string.IsNullOrWhiteSpace(text))
            {
                return(text);
            }

            if (TryGetTemplate(text.Trim(), out var template))
            {
                var vars = new TemplateVars
                {
                    ["event"] = @event
                };

                return(await templateEngine.RenderAsync(template, vars));
            }

            if (TryGetScript(text.Trim(), out var script))
            {
                var vars = new ScriptVars
                {
                    ["event"] = @event
                };

#pragma warning disable MA0042 // Do not use blocking calls in an async method
                var result = scriptEngine.Execute(vars, script).ToString();
#pragma warning restore MA0042 // Do not use blocking calls in an async method

                if (result == "undefined")
                {
                    return(GlobalFallback);
                }

                return(result);
            }

            var parts = BuildParts(text, @event);

            if (parts.Any(x => !x.Var.IsCompleted))
            {
                await ValueTaskEx.WhenAll(parts.Select(x => x.Var));
            }

            return(CombineParts(text, parts));
        }
Beispiel #14
0
        public async Task Should_resolve_references_in_loop()
        {
            var referenceId1 = DomainId.NewGuid();
            var reference1   = CreateReference(referenceId1, 1);
            var referenceId2 = DomainId.NewGuid();
            var reference2   = CreateReference(referenceId1, 2);

            var @event = new EnrichedContentEvent
            {
                Data =
                    new NamedContentData()
                    .AddField("references",
                              new ContentFieldData()
                              .AddJsonValue(JsonValue.Array(referenceId1, referenceId2))),
                AppId = appId
            };

            A.CallTo(() => contentQuery.QueryAsync(A <Context> ._, A <IReadOnlyList <DomainId> > .That.Contains(referenceId1)))
            .Returns(ResultList.CreateFrom(1, reference1));

            A.CallTo(() => contentQuery.QueryAsync(A <Context> ._, A <IReadOnlyList <DomainId> > .That.Contains(referenceId2)))
            .Returns(ResultList.CreateFrom(1, reference2));

            var vars = new TemplateVars
            {
                ["event"] = @event
            };

            var template = @"
{% for id in event.data.references.iv %}
    {% reference 'ref', id %}
    Text: {{ ref.data.field1.iv }} {{ ref.data.field2.iv }}
{% endfor %}
";

            var expected = @"
    Text: Hello 1 World 1
    Text: Hello 2 World 2
";

            var result = await sut.RenderAsync(template, vars);

            Assert.Equal(expected, result);
        }
Beispiel #15
0
        public async Task Should_resolve_assets_in_loop()
        {
            var assetId1 = DomainId.NewGuid();
            var asset1   = CreateAsset(assetId1, 1);
            var assetId2 = DomainId.NewGuid();
            var asset2   = CreateAsset(assetId2, 2);

            var @event = new EnrichedContentEvent
            {
                Data =
                    new ContentData()
                    .AddField("assets",
                              new ContentFieldData()
                              .AddInvariant(JsonValue.Array(assetId1, assetId2))),
                AppId = appId
            };

            A.CallTo(() => assetQuery.FindAsync(A <Context> ._, assetId1, EtagVersion.Any, A <CancellationToken> ._))
            .Returns(asset1);

            A.CallTo(() => assetQuery.FindAsync(A <Context> ._, assetId2, EtagVersion.Any, A <CancellationToken> ._))
            .Returns(asset2);

            var vars = new TemplateVars
            {
                ["event"] = @event
            };

            var template = @"
                {% for id in event.data.assets.iv %}
                    {% asset 'ref', id %}
                    Text: {{ ref.fileName }} {{ ref.id }}
                {% endfor %}
                ";

            var expected = $@"
                Text: file1.jpg {assetId1}
                Text: file2.jpg {assetId2}
            ";

            var result = await sut.RenderAsync(template, vars);

            Assert.Equal(Cleanup(expected), Cleanup(result));
        }
        public async Task Should_resolve_references_in_loop_with_filter()
        {
            var referenceId1 = DomainId.NewGuid();
            var reference1   = CreateReference(referenceId1, 1);
            var referenceId2 = DomainId.NewGuid();
            var reference2   = CreateReference(referenceId2, 2);

            var @event = new EnrichedContentEvent
            {
                Data =
                    new ContentData()
                    .AddField("references",
                              new ContentFieldData()
                              .AddInvariant(JsonValue.Array(referenceId1, referenceId2))),
                AppId = appId
            };

            A.CallTo(() => contentQuery.QueryAsync(A <Context> ._, A <Q> .That.HasIds(referenceId1), A <CancellationToken> ._))
            .Returns(ResultList.CreateFrom(1, reference1));

            A.CallTo(() => contentQuery.QueryAsync(A <Context> ._, A <Q> .That.HasIds(referenceId2), A <CancellationToken> ._))
            .Returns(ResultList.CreateFrom(1, reference2));

            var vars = new TemplateVars
            {
                ["event"] = @event
            };

            var template = @"
                {% for id in event.data.references.iv %}
                    {% assign ref = id | reference %}
                    Text: {{ ref.data.field1.iv }} {{ ref.data.field2.iv }} {{ ref.id }}
                {% endfor %}
            ";

            var expected = $@"
                Text: Hello 1 World 1 {referenceId1}
                Text: Hello 2 World 2 {referenceId2}
            ";

            var result = await sut.RenderAsync(template, vars);

            Assert.Equal(Cleanup(expected), Cleanup(result));
        }
Beispiel #17
0
        private void StartScaffoldingAsync(Object sender, EventArgs e)
        {
            var logger             = new RichTextBoxLogger(log, sender as BackgroundWorker);
            var templateVars       = new TemplateVars(TableName, TableColumns, ProjectItem.Name);
            var templateProvider   = GetTemplateProvider();
            var codeCommentator    = new CodeCommentator();
            var vsProjectPersister = new VsProjectFilePersister(ProjectItem, codeCommentator, logger);

            TableDesignerVisible  = false;
            ScaffoldingLogVisible = true;

            var scaffolder = new TableScaffolder(
                templateVars,
                templateProvider,
                vsProjectPersister,
                ProjectItem,
                logger);

            scaffolder.Scaffold();
        }
        public Template Compile(TemplateVars templateVars, ILogger logger)
        {
            try
            {
                // Override default delimiters, these will not require as
                // much escaping in C# code as default delimiters
                var template = new Template(Template, '$', '$');
                foreach (var templateVar in templateVars)
                {
                    template.Add(templateVar.Key, templateVar.Value);
                }

                // Register string renderer so that we can user "Upper" modifier in templates
                template.Group.RegisterRenderer(typeof(string), new StringRenderer());

                return template;
            }
            catch (Exception e)
            {
                // Ups, something is worng with the template
                logger.Error(string.Format("Invalid template {0}. {1}", FileName, e.Message));
                return null;
            }
        }
Beispiel #19
0
        public async ValueTask <string?> FormatAsync(string text, EnrichedEvent @event)
        {
            if (string.IsNullOrWhiteSpace(text))
            {
                return(text);
            }

            if (TryGetTemplate(text.Trim(), out var template))
            {
                var vars = new TemplateVars
                {
                    ["event"] = @event
                };

                return(await templateEngine.RenderAsync(template, vars));
            }

            if (TryGetScript(text.Trim(), out var script))
            {
                var vars = new ScriptVars
                {
                    ["event"] = @event
                };

                return(scriptEngine.Interpolate(vars, script));
            }

            var parts = BuildParts(text, @event);

            if (parts.Any(x => !x.Var.IsCompleted))
            {
                await ValueTaskEx.WhenAll(parts.Select(x => x.Var));
            }

            return(CombineParts(text, parts));
        }
        private void StartScaffoldingAsync(Object sender, EventArgs e)
        {
            var logger = new RichTextBoxLogger(log, sender as BackgroundWorker);
            var templateVars = new TemplateVars(TableName, TableColumns, ProjectItem.Name);
            var templateProvider = GetTemplateProvider();
            var codeCommentator = new CodeCommentator();
            var vsProjectPersister = new VsProjectFilePersister(ProjectItem, codeCommentator, logger);

            TableDesignerVisible = false;
            ScaffoldingLogVisible = true;

            var scaffolder = new TableScaffolder(
                templateVars,
                templateProvider,
                vsProjectPersister,
                ProjectItem,
                logger);

            scaffolder.Scaffold();
        }
 /// <summary>
 /// Generates full path to the destination file and replaces all
 /// placeholders with a corresponding template variable
 /// </summary>
 public string CompileFullPath(TemplateVars templateVars, string basePath)
 {
     var fullPath = Path.Combine(basePath, RelativePath, FileName);
     foreach (var templateVar in templateVars)
     {
         var key = string.Format("_{0}_", templateVar.Key);
         fullPath = fullPath.Replace(key, templateVar.Value.ToString());
     }
     return fullPath;
 }
Beispiel #22
0
 public SharpTLDefaultTemplate(TemplateVars templateVars)
 {
     _templateVars = templateVars;
 }
Beispiel #23
0
 public SchemaMethodsImplTemplate(TemplateVars templateVars)
 {
     _templateVars = templateVars;
 }
Beispiel #24
0
        protected void FinishTemplate(int escapeCount)
        {
            RCString     section;
            TemplateVars template = _templates.Peek();

            if (template._multilineTemplate)
            {
                for (int i = 0; i < _block.Count; ++i)
                {
                    RCBlock current = _block.GetName(i);
                    section = current.Value as RCString;
                    if (section != null && i % 2 == 0)
                    {
                        string content      = section[0];
                        int    spaces       = 0;
                        bool   broken       = false;
                        bool   hasLine      = false;
                        int    firstNewline = content.IndexOf('\n');
                        if (firstNewline > -1)
                        {
                            hasLine = true;
                        }
                        for (int j = firstNewline + 1; j < content.Length; ++j)
                        {
                            if (content[j] == ' ')
                            {
                                if (!broken)
                                {
                                    ++spaces;
                                }
                            }
                            else if (content[j] == '\n')
                            {
                                if (j > 0)
                                {
                                    template._minSpaces = Math.Min(template._minSpaces, spaces);
                                }
                                spaces  = 0;
                                broken  = false;
                                hasLine = true;
                            }
                            else
                            {
                                broken = true;
                            }
                        }
                        if (content.Length > 0 &&
                            content[content.Length - 1] != '\n' &&
                            hasLine &&
                            i < _block.Count - 1)
                        {
                            template._minSpaces = Math.Min(template._minSpaces, spaces);
                        }
                        if (template._minSpaces == int.MaxValue)
                        {
                            template._minSpaces = 0;
                        }
                    }
                }

                RCBlock final = RCBlock.Empty;
                // strip indentation (spaces only) from the lines in the content.
                // Ignore the first and last sections.
                for (int i = 0; i < _block.Count; ++i)
                {
                    RCBlock current = _block.GetName(i);
                    section = current.Value as RCString;
                    if (section != null && i % 2 == 0)
                    {
                        string        content = section[0];
                        StringBuilder builder = new StringBuilder();

                        int start = 0, end = 0;
                        // Skip past the initial newline in the first section.
                        if (i == 0)
                        {
                            while (content[start] != '\n')
                            {
                                ++start;
                            }
                            ++start;
                        }
                        else
                        {
                            while (end < content.Length)
                            {
                                if (content[end] == '\n')
                                {
                                    ++end;
                                    break;
                                }
                                ++end;
                            }
                            if (end < content.Length && end > 1 && content[end - 2] == '\r')
                            {
                                builder.Append(content.Substring(start, (end - 2) - start));
                                builder.Append("\n");
                            }
                            else
                            {
                                builder.Append(content.Substring(start, end - start));
                            }
                            start = end;
                        }
                        end = start;

GETLINE:
                        start = end + template._minSpaces;

                        while (end < content.Length)
                        {
                            if (content[end] == '\n')
                            {
                                ++end;
                                break;
                            }
                            ++end;
                        }

                        // The problem is when the first character is a newline this gets f****d up.
                        if (start < content.Length && end <= content.Length)
                        {
                            // string trimmed;
                            if (end < start)
                            {
                                builder.Append(content.Substring(0, end));
                            }
                            else
                            {
                                if (content.Length > 1 && content[end - 2] == '\r')
                                {
                                    builder.Append(content.Substring(start, (end - 2) - start));
                                    builder.Append("\n");
                                }
                                else
                                {
                                    builder.Append(content.Substring(start, end - start));
                                }
                            }
                            // builder.Append (trimmed);
                            goto GETLINE;
                        }
                        else
                        {
                            final = new RCBlock(final,
                                                current.Name,
                                                current.Evaluator,
                                                new RCString(builder.ToString()));
                        }
                    }
                    else
                    {
                        final = new RCBlock(final, current.Name, current.Evaluator, current.Value);
                    }
                }
                _result = new RCTemplate(final, escapeCount, true);
            }
            else
            {
                _result = new RCTemplate(_block, escapeCount, false);
            }

            // The template must either be all on one line,
            // or the first and last lines with the [? and ?] tokens
            // must be free of any other content.
            // So this loop needs to find out whether there are any newlines.
            // If there are then we also need to find out where the
            // first non-white character is.

            // Reset state for the possible next template.
            // _multilineTemplate = false;
            // _parsingContent = false;
            // _minSpaces = 0;
        }