/// <summary>
        /// Process the specified input template and return the result.
        /// </summary>
        /// <param name="inputTemplate"></param>
        /// <returns></returns>
        public LavaRenderResult GetTemplateRenderResult(ILavaEngine engine, string inputTemplate, LavaRenderParameters parameters = null, LavaTestRenderOptions options = null)
        {
            inputTemplate = inputTemplate ?? string.Empty;

            var context = engine.NewRenderContext();

            if (parameters == null)
            {
                parameters = LavaRenderParameters.WithContext(context);
            }

            // If options are specified, replace the render parameters.
            if (options != null)
            {
                context.SetEnabledCommands(options.EnabledCommands, options.EnabledCommandsDelimiter);
                context.SetMergeFields(options.MergeFields);

                if (options.ExceptionHandlingStrategy != null)
                {
                    parameters.ExceptionHandlingStrategy = options.ExceptionHandlingStrategy;
                }
            }

            var result = engine.RenderTemplate(inputTemplate.Trim(), parameters);

            return(result);
        }
Beispiel #2
0
        private LavaRenderResult ExecuteSqlBlock(ILavaEngine engine, string lavaScript)
        {
            var renderContext = engine.NewRenderContext(new List <string> {
                "Sql"
            });

            var result = engine.RenderTemplate(lavaScript,
                                               new LavaRenderParameters {
                Context = renderContext, ExceptionHandlingStrategy = ExceptionHandlingStrategySpecifier.RenderToOutput
            });

            return(result);
        }
Beispiel #3
0
        /// <summary>
        /// Creates a new Lava render context instance.
        /// </summary>
        /// <returns></returns>
        public static ILavaRenderContext NewRenderContext()
        {
            if (_engine == null)
            {
                return(null);
            }

            return(_engine.NewRenderContext());
        }
Beispiel #4
0
        /// <summary>
        /// Process the specified input template and return the result.
        /// </summary>
        /// <param name="inputTemplate"></param>
        /// <returns></returns>
        public string GetTemplateOutput(ILavaEngine engine, string inputTemplate, LavaDataDictionary mergeValues = null)
        {
            inputTemplate = inputTemplate ?? string.Empty;

            if (engine == null)
            {
                throw new Exception("Engine instance is required.");
            }

            var context = engine.NewRenderContext(mergeValues);

            return(GetTemplateOutput(engine, inputTemplate, new LavaRenderParameters {
                Context = context
            }));
        }
        /// <summary>
        /// Verify that the specified template is invalid.
        /// </summary>
        /// <param name="inputTemplate"></param>
        /// <returns></returns>
        public void AssertTemplateIsInvalid(ILavaEngine engine, string inputTemplate, LavaDataDictionary mergeFields = null)
        {
            inputTemplate = inputTemplate ?? string.Empty;

            Assert.That.ThrowsException <LavaException>(
                () =>
            {
                var renderOptions = new LavaRenderParameters
                {
                    Context = engine.NewRenderContext(mergeFields),
                    ExceptionHandlingStrategy = ExceptionHandlingStrategySpecifier.Throw
                };

                _ = engine.RenderTemplate(inputTemplate.Trim(), renderOptions);
            },
                "Invalid template expected.");
        }
        /// <summary>
        /// Process the specified input template and return the result.
        /// </summary>
        /// <param name="inputTemplate"></param>
        /// <returns></returns>
        public string GetTemplateOutput(ILavaEngine engine, string inputTemplate, LavaTestRenderOptions options)
        {
            inputTemplate = inputTemplate ?? string.Empty;

            var context = engine.NewRenderContext();

            var parameters = LavaRenderParameters.WithContext(context);

            if (options != null)
            {
                context.SetEnabledCommands(options.EnabledCommands, options.EnabledCommandsDelimiter);
                context.SetMergeFields(options.MergeFields);

                parameters.ExceptionHandlingStrategy = options.ExceptionHandlingStrategy;
            }

            var result = engine.RenderTemplate(inputTemplate.Trim(), parameters);

            return(result.Text);
        }
Beispiel #7
0
        /// <summary>
        /// Renders the specified context.
        /// </summary>
        /// <param name="context">The context.</param>
        /// <param name="result">The result.</param>
        public override void OnRender(ILavaRenderContext context, TextWriter result)
        {
            if (_shortcode == null)
            {
                result.Write($"An error occurred while processing the {0} shortcode.", _tagName);
            }

            // Get the parameters and default values defined by the shortcode, then apply the parameters that have been specified in the shortcode tag attributes
            // and those that are stored in the current render context.
            var parms = new Dictionary <string, object>();

            foreach (var shortcodeParm in _shortcode.Parameters)
            {
                parms.AddOrReplace(shortcodeParm.Key, shortcodeParm.Value);
            }

            SetParametersFromElementAttributes(parms, _elementAttributesMarkup, context);

            // Set a unique id for the shortcode.
            parms.AddOrReplace("uniqueid", "id-" + Guid.NewGuid().ToString());

            // Apply the merge fields in the block context.
            var internalMergeFields = context.GetMergeFields();

            foreach (var item in parms)
            {
                internalMergeFields.AddOrReplace(item.Key, item.Value);
            }

            // Add parameters for tracking the recursion depth.
            int currentRecursionDepth = 0;

            if (parms.ContainsKey("RecursionDepth"))
            {
                currentRecursionDepth = parms["RecursionDepth"].ToString().AsInteger() + 1;

                if (currentRecursionDepth > _maxRecursionDepth)
                {
                    result.Write("A recursive loop was detected and processing of this shortcode has stopped.");
                    return;
                }
            }

            parms.AddOrReplace("RecursionDepth", currentRecursionDepth);

            // Resolve the merge fields in the shortcode template in a separate context, using the set of merge fields that have been modified by the shortcode parameters.
            // Apply the set of enabled commands specified by the shortcode definition, or those enabled for the current context if none are defined by the shortcode.
            // The resulting content is a shortcode template that is ready to be processed to resolve its child elements.
            var enabledCommands = _shortcode.EnabledLavaCommands ?? new List <string>();

            enabledCommands = enabledCommands.Where(x => !string.IsNullOrWhiteSpace(x)).ToList();

            if (!enabledCommands.Any())
            {
                enabledCommands = context.GetEnabledCommands();
            }

            var shortcodeTemplateContext = _engine.NewRenderContext(internalMergeFields, enabledCommands);

            var blockMarkupRenderResult = _engine.RenderTemplate(_blockMarkup.ToString(), LavaRenderParameters.WithContext(shortcodeTemplateContext));

            var shortcodeTemplateMarkup = blockMarkupRenderResult.Text;

            // Extract child elements from the shortcode template content.
            // One or more child elements can be added to a shortcode block using the syntax "[[ <childElementName> <paramName1>:value1 <paramName2>:value2 ... ]] ... [[ end<childElementName> ]]",
            // where <childElementName> is a shortcode-specific tag name, <param1> is a shortcode parameter name, and <value1> is the parameter value.
            // Child elements are grouped by <childElementName>, and each collection is passed as a separate parameter to the shortcode template
            // using the variable name "<childElementNameItems>". The first element of the array is also added using the variable name "<childElementName>".
            // Parameters declared on child elements can be referenced in the shortcode template as <childElementName>.<paramName>.
            Dictionary <string, object> childElements;

            var residualMarkup = ExtractShortcodeBlockChildElements(shortcodeTemplateMarkup, out childElements);

            // Add the collections of child to the set of parameters that will be passed to the shortcode template.
            foreach (var item in childElements)
            {
                parms.AddOrReplace(item.Key, item.Value);
            }

            // Set context variables related to the block content so they can be referenced by the shortcode template.
            if (residualMarkup.IsNotNullOrWhiteSpace())
            {
                // JME (7/23/2019) Commented out the two lines below and substituted the line after to allow for better
                // processing of the block content. Testing was done on all existing shortcodes but leaving
                // this code in place in case a future edge case is found. Could/should remove this in the future.
                // Regex rgx = new Regex( @"{{\s*blockContent\s*}}", RegexOptions.IgnoreCase );
                // lavaTemplate = rgx.Replace( lavaTemplate, blockMarkup );
                parms.AddOrReplace("blockContent", residualMarkup);

                parms.AddOrReplace("blockContentExists", true);
            }
            else
            {
                parms.AddOrReplace("blockContentExists", false);
            }

            // Now ensure there aren't any entity commands in the block that are not allowed.
            // This is necessary because the shortcode may be configured to allow more entities for processing
            // than the source block, template, action, etc. permits.
            var securityCheckResult = _engine.RenderTemplate(residualMarkup, LavaRenderParameters.WithContext(context));

            Regex securityErrorPattern = new Regex(string.Format(Constants.Messages.NotAuthorizedMessage, ".*"));
            Match securityErrorMatch   = securityErrorPattern.Match(securityCheckResult.Text);

            // If the security check failed, return the error message.
            if (securityErrorMatch.Success)
            {
                result.Write(securityErrorMatch.Value);

                return;
            }

            // Merge the shortcode template in a new context, using the parameters and security allowed by the shortcode.
            var shortcodeContext = _engine.NewRenderContext(parms);

            // If the shortcode specifies a set of enabled Lava commands, set these for the current context.
            // If not, use the commands enabled for the current context.
            if (_shortcode.EnabledLavaCommands != null &&
                _shortcode.EnabledLavaCommands.Any())
            {
                shortcodeContext.SetEnabledCommands(_shortcode.EnabledLavaCommands);
            }
            else
            {
                shortcodeContext.SetEnabledCommands(context.GetEnabledCommands());
            }

            var results = _engine.RenderTemplate(_shortcode.TemplateMarkup, LavaRenderParameters.WithContext(shortcodeContext));

            result.Write(results.Text.Trim());
        }
Beispiel #8
0
        /// <summary>
        /// Process the specified input template and verify against the expected output.
        /// </summary>
        /// <param name="expectedOutput"></param>
        /// <param name="inputTemplate"></param>
        public void AssertTemplateOutput(ILavaEngine engine, string expectedOutput, string inputTemplate, LavaDataDictionary mergeValues = null, bool ignoreWhitespace = false)
        {
            var context = engine.NewRenderContext(mergeValues);

            AssertTemplateOutput(engine, expectedOutput, inputTemplate, LavaRenderParameters.WithContext(context), ignoreWhitespace);
        }