/// <inheritdoc />
        public override async ItemExecutionPromise Render(IByteCounterStream outputStream, ContextObject context, ScopeData scopeData)
        {
            context = await MorestachioExpression.GetValue(context, scopeData);

            scopeData.AddVariable(Value, context, IdVariableScope);
            return(Enumerable.Empty <DocumentItemExecution>());
        }
        /// <inheritdoc />
        public override async ItemExecutionPromise Render(IByteCounterStream outputStream,
                                                          ContextObject context,
                                                          ScopeData scopeData)
        {
            string partialName    = Value;
            var    currentPartial = partialName + "_" + scopeData.PartialDepth.Count;

            scopeData.PartialDepth.Push(currentPartial);
            if (scopeData.PartialDepth.Count >= context.Options.PartialStackSize)
            {
                switch (context.Options.StackOverflowBehavior)
                {
                case PartialStackOverflowBehavior.FailWithException:
                    throw new MustachioStackOverflowException(
                              $"You have exceeded the maximum stack Size for nested Partial calls of '{context.Options.PartialStackSize}'. See Data for call stack")
                          {
                              Data =
                              {
                                  { "Callstack", scopeData.PartialDepth }
                              }
                          };

                case PartialStackOverflowBehavior.FailSilent:
                    return(new DocumentItemExecution[0]);

                default:
                    throw new ArgumentOutOfRangeException();
                }
            }

            var cnxt = context;

            if (Context != null)
            {
                cnxt = (await Context.GetValue(context, scopeData));
            }

            scopeData.AddVariable("$recursion",
                                  (scope) => cnxt.Options.CreateContextObject("$recursion", context.CancellationToken,
                                                                              scope.PartialDepth.Count, cnxt), 0);

            if (scopeData.Partials.TryGetValue(partialName, out var partialWithContext))
            {
                return(new[]
                {
                    new DocumentItemExecution(partialWithContext, cnxt),
                    new DocumentItemExecution(new RenderPartialDoneDocumentItem(), cnxt),
                });
            }

            var partialFromStore = context.Options.PartialsStore?.GetPartial(partialName)?.Document;

            if (partialFromStore != null)
            {
                return(new[]
                {
                    new DocumentItemExecution(partialFromStore, cnxt),
                    new DocumentItemExecution(new RenderPartialDoneDocumentItem(), cnxt),
                });
            }

            throw new MorestachioRuntimeException($"Could not obtain a partial named '{partialName}' from the template nor the Partial store");
        }
Esempio n. 3
0
 private void CoreAction(ContextObject context, ScopeData scopeData)
 {
     scopeData.AddVariable(Value, context, IdVariableScope);
 }
        /// <inheritdoc />
        public override async ItemExecutionPromise Render(IByteCounterStream outputStream,
                                                          ContextObject context,
                                                          ScopeData scopeData)
        {
            string partialName = Value;

            scopeData.PartialDepth.Push(new Tuple <string, int>(partialName, scopeData.PartialDepth.Count));
            if (scopeData.PartialDepth.Count >= scopeData.ParserOptions.PartialStackSize)
            {
                switch (scopeData.ParserOptions.StackOverflowBehavior)
                {
                case PartialStackOverflowBehavior.FailWithException:
                    throw new MustachioStackOverflowException(
                              $"You have exceeded the maximum stack Size for nested Partial calls of '{scopeData.ParserOptions.PartialStackSize}'. See Data for call stack")
                          {
                              Data =
                              {
                                  { "Callstack", scopeData.PartialDepth }
                              }
                          };

                case PartialStackOverflowBehavior.FailSilent:
                    return(new DocumentItemExecution[0]);

                default:
                    throw new ArgumentOutOfRangeException();
                }
            }

            var cnxt = context;

            scopeData.AddVariable("$name",
                                  (scope) => scopeData.ParserOptions.CreateContextObject("$name", partialName, cnxt), 0);

            if (Context != null)
            {
                cnxt = (await Context.GetValue(context, scopeData));
            }

            scopeData.AddVariable("$recursion",
                                  (scope) => scopeData.ParserOptions.CreateContextObject("$recursion", scope.PartialDepth.Count, cnxt), 0);

            if (scopeData.Partials.TryGetValue(partialName, out var partialWithContext))
            {
                return(new[]
                {
                    new DocumentItemExecution(partialWithContext, cnxt),
                    new DocumentItemExecution(new RenderPartialDoneDocumentItem(), cnxt),
                });
            }


            if (scopeData.ParserOptions.PartialsStore != null)
            {
                MorestachioDocumentInfo partialFromStore;
                if (scopeData.ParserOptions.PartialsStore is IAsyncPartialsStore asyncPs)
                {
                    partialFromStore = await asyncPs.GetPartialAsync(partialName, scopeData.ParserOptions);
                }
                else
                {
                    partialFromStore = scopeData.ParserOptions.PartialsStore.GetPartial(partialName, scopeData.ParserOptions);
                }

                if (partialFromStore != null)
                {
                    if (partialFromStore.Errors.Any())
                    {
                        throw new MorestachioRuntimeException($"The partial named '{partialName}' obtained from external partial store contains one or more errors");
                    }

                    return(new[]
                    {
                        new DocumentItemExecution(partialFromStore.Document, cnxt),
                        new DocumentItemExecution(new RenderPartialDoneDocumentItem(), cnxt),
                    });
                }
            }


            throw new MorestachioRuntimeException($"Could not obtain a partial named '{partialName}' from the template nor the Partial store");
        }
        private async CoreActionPromise CoreAction(
            ContextObject context,
            ScopeData scopeData,
            Func <string, ContextObject, BooleanPromise> obtainPartialFromStore,
            string partialName)
        {
            scopeData.PartialDepth.Push(new Tuple <string, int>(partialName, scopeData.PartialDepth.Count));
            if (scopeData.PartialDepth.Count >= scopeData.ParserOptions.PartialStackSize)
            {
                switch (scopeData.ParserOptions.StackOverflowBehavior)
                {
                case PartialStackOverflowBehavior.FailWithException:
                    throw new MustachioStackOverflowException(
                              $"You have exceeded the maximum stack Size for nested Partial calls of '{scopeData.ParserOptions.PartialStackSize}'. See Data for call stack")
                          {
                              Data =
                              {
                                  { "Callstack", scopeData.PartialDepth }
                              }
                          };

                case PartialStackOverflowBehavior.FailSilent:
                    return(null);

                default:
                    throw new ArgumentOutOfRangeException();
                }
            }

            scopeData.AddVariable("$name",
                                  (scope) => scopeData.ParserOptions.CreateContextObject("$name", scope.PartialDepth.Peek().Item1, context), 0);

            var cnxt = context;

            if (Context != null)
            {
                cnxt = (await Context.GetValue(context, scopeData));
            }

            cnxt = cnxt.Copy().MakeNatural();

            scopeData.AddVariable("$recursion",
                                  (scope) => scopeData.ParserOptions.CreateContextObject("$recursion", scope.PartialDepth.Count, cnxt), 0);

            if (await obtainPartialFromStore(partialName, cnxt))
            {
                return(null);
            }

            if (scopeData.ParserOptions.PartialsStore != null)
            {
                MorestachioDocumentInfo partialFromStore;
                if (scopeData.ParserOptions.PartialsStore is IAsyncPartialsStore asyncPs)
                {
                    partialFromStore = await asyncPs.GetPartialAsync(partialName, scopeData.ParserOptions);
                }
                else
                {
                    partialFromStore = scopeData.ParserOptions.PartialsStore.GetPartial(partialName, scopeData.ParserOptions);
                }

                if (partialFromStore != null)
                {
                    if (partialFromStore.Errors.Any())
                    {
                        throw new MorestachioRuntimeException($"The partial named '{partialName}' obtained from external partial store contains one or more errors");
                    }

                    return(Tuple.Create(partialFromStore.Document, cnxt));
                }
            }

            throw new MorestachioRuntimeException($"Could not obtain a partial named '{partialName}' from the template nor the Partial store");
        }
 /// <inheritdoc />
 public override ItemExecutionPromise Render(IByteCounterStream outputStream, ContextObject context, ScopeData scopeData)
 {
     scopeData.AddVariable(Value, context, IdVariableScope);
     return(Children.WithScope(context).ToPromise());
 }