예제 #1
0
        /// <summary>
        /// Create a new template context containing the specified merge fields.
        /// </summary>
        /// <param name="mergeFields"></param>
        /// <returns></returns>
        protected override ILavaRenderContext OnCreateRenderContext()
        {
            var fluidContext = new global::Fluid.TemplateContext(_templateOptions);
            var context      = new FluidRenderContext(fluidContext);

            return(context);
        }
예제 #2
0
        /// <summary>
        /// Registers a set of Liquid-style filter functions for use with the Fluid templating engine.
        /// The original filters are wrapped in a function with a Fluid-compatible signature so they can be called by Fluid.
        /// </summary>
        /// <param name="lavaFilterMethod">The MethodInfo object that describes the function.</param>
        /// <param name="filterName">The Lava name for the filter.</param>
        protected override void OnRegisterFilter(MethodInfo lavaFilterMethod, string filterName)
        {
            var lavaFilterMethodParameters = lavaFilterMethod.GetParameters();

            if (lavaFilterMethodParameters.Length == 0)
            {
                return;
            }

            var templateOptions = GetTemplateOptions();

            filterName = filterName ?? lavaFilterMethod.Name;

            // The first argument passed to the Lava filter is either the Lava Context or the template input.
            var hasContextParameter = lavaFilterMethodParameters[0].ParameterType == typeof(ILavaRenderContext);

            var firstParameterIndex = 1 + (hasContextParameter ? 1 : 0);

            // Define the Fluid-compatible filter function that will wrap the Lava filter method.
            ValueTask <FluidValue> fluidFilterFunction(FluidValue input, FilterArguments arguments, TemplateContext context)
            {
                var lavaFilterMethodArguments = new object[lavaFilterMethodParameters.Length];

                for (int i = 0; i < lavaFilterMethodParameters.Length; i++)
                {
                    FluidValue fluidFilterArgument = null;

                    // Get the value for the argument.
                    if (i == 0)
                    {
                        // If this is the first parameter, it may be a LavaContext or the input template.
                        if (hasContextParameter)
                        {
                            lavaFilterMethodArguments[0] = new FluidRenderContext(context);
                            continue;
                        }
                        else
                        {
                            fluidFilterArgument = input;
                        }
                    }
                    else if (i == 1 && hasContextParameter)
                    {
                        // If this is the second parameter, it must be the input template if the first parameter is a LavaContext.
                        fluidFilterArgument = input;
                    }
                    else if (arguments.Count > (i - firstParameterIndex))
                    {
                        // This parameter is a filter argument.
                        fluidFilterArgument = arguments.At(i - firstParameterIndex);
                    }

                    if (fluidFilterArgument == null && lavaFilterMethodParameters[i].IsOptional)
                    {
                        lavaFilterMethodArguments[i] = lavaFilterMethodParameters[i].DefaultValue;
                    }
                    else
                    {
                        lavaFilterMethodArguments[i] = GetLavaParameterArgumentFromFluidValue(fluidFilterArgument, lavaFilterMethodParameters[i].ParameterType);
                    }
                }

                try
                {
                    var result = lavaFilterMethod.Invoke(null, lavaFilterMethodArguments);

                    return(FluidValue.Create(result, templateOptions));
                }
                catch (TargetInvocationException ex)
                {
                    // Any exceptions thrown from the filter method are wrapped in a TargetInvocationException by the .NET framework.
                    // Rethrow the actual exception thrown by the filter, where possible.
                    throw ex.InnerException ?? ex;
                }
            }

            templateOptions.Filters.AddFilter(filterName, fluidFilterFunction);
        }