コード例 #1
0
        public override async ValueTask <Completion> WriteToAsync(TextWriter writer, TextEncoder encoder, TemplateContext context, Expression expression, FilterArgument[] args)
        {
            var objectValue = (await expression.EvaluateAsync(context)).ToObjectValue() as dynamic;

            if (objectValue is Shape shape)
            {
                var arguments = (FilterArguments)(await new ArgumentsExpression(args).EvaluateAsync(context)).ToObjectValue();

                if (shape.Metadata.Type == "PagerSlim")
                {
                    foreach (var name in arguments.Names)
                    {
                        var argument     = arguments[name];
                        var propertyName = LiquidViewFilters.LowerKebabToPascalCase(name);

                        if (_properties.Contains(propertyName))
                        {
                            objectValue[propertyName] = argument.ToStringValue();
                        }
                    }
                }

                if (shape.Metadata.Type == "PagerSlim" || shape.Metadata.Type == "Pager")
                {
                    if (arguments.Names.Contains("item_classes"))
                    {
                        var classes = arguments["item_classes"];

                        if (classes.Type == FluidValues.String)
                        {
                            var values = classes.ToStringValue().Split(new[] { ' ' }, StringSplitOptions.RemoveEmptyEntries);

                            foreach (var value in values)
                            {
                                objectValue.ItemClasses.Add(value);
                            }
                        }

                        else if (classes.Type == FluidValues.Array)
                        {
                            foreach (var value in classes.Enumerate())
                            {
                                objectValue.ItemClasses.Add(value.ToStringValue());
                            }
                        }
                    }
                }
            }

            return(Completion.Normal);
        }
コード例 #2
0
ファイル: HelperTag.cs プロジェクト: sadikkahveci/OrchardCore
        public override async Task <Completion> WriteToAsync(TextWriter writer, TextEncoder encoder, TemplateContext context)
        {
            if (!context.AmbientValues.TryGetValue("Services", out var servicesValue))
            {
                throw new ArgumentException("Services missing while invoking 'helper'");
            }

            var services = servicesValue as IServiceProvider;

            if (!context.AmbientValues.TryGetValue("ViewContext", out var viewContext))
            {
                throw new ArgumentException("ViewContext missing while invoking 'helper'");
            }

            var arguments = (FilterArguments)(await _arguments.EvaluateAsync(context)).ToObjectValue();

            var helper = _helper ?? arguments.At(0).ToStringValue();
            var tagHelperSharedState = services.GetRequiredService <TagHelperSharedState>();

            if (tagHelperSharedState.TagHelperDescriptors == null)
            {
                lock (tagHelperSharedState)
                {
                    if (tagHelperSharedState.TagHelperDescriptors == null)
                    {
                        var razorEngine      = services.GetRequiredService <RazorEngine>();
                        var tagHelperFeature = razorEngine.Features.OfType <ITagHelperFeature>().FirstOrDefault();
                        tagHelperSharedState.TagHelperDescriptors = tagHelperFeature.GetDescriptors().ToList();
                    }
                }
            }

            if (_descriptor == null)
            {
                lock (this)
                {
                    var descriptors = tagHelperSharedState.TagHelperDescriptors
                                      .Where(d => d.TagMatchingRules.Any(rule => ((rule.TagName == "*") ||
                                                                                  rule.TagName == helper) && rule.Attributes.All(attr => arguments.Names.Any(name =>
                    {
                        if (String.Equals(name, attr.Name, StringComparison.OrdinalIgnoreCase))
                        {
                            return(true);
                        }

                        name = name.Replace("_", "-");

                        if (attr.Name.StartsWith(AspPrefix) && String.Equals(name,
                                                                             attr.Name.Substring(AspPrefix.Length), StringComparison.OrdinalIgnoreCase))
                        {
                            return(true);
                        }

                        if (String.Equals(name, attr.Name, StringComparison.OrdinalIgnoreCase))
                        {
                            return(true);
                        }

                        return(false);
                    }))));

                    _descriptor = descriptors.FirstOrDefault();

                    if (_descriptor == null)
                    {
                        return(Completion.Normal);
                    }
                }
            }

            var tagHelperType = Type.GetType(_descriptor.Name + ", " + _descriptor.AssemblyName);

            var _tagHelperActivator = _tagHelperActivators.GetOrAdd(tagHelperType, key =>
            {
                var genericFactory = typeof(ReusableTagHelperFactory <>).MakeGenericType(key);
                var factoryMethod  = genericFactory.GetMethod("CreateTagHelper");

                return(Delegate.CreateDelegate(typeof(Func <ITagHelperFactory, ViewContext, ITagHelper>), factoryMethod) as Func <ITagHelperFactory, ViewContext, ITagHelper>);
            });

            var tagHelperFactory = services.GetRequiredService <ITagHelperFactory>();
            var tagHelper        = _tagHelperActivator(tagHelperFactory, (ViewContext)viewContext);

            var attributes = new TagHelperAttributeList();

            foreach (var name in arguments.Names)
            {
                var propertyName = LiquidViewFilters.LowerKebabToPascalCase(name);

                var found = false;
                foreach (var attribute in _descriptor.BoundAttributes)
                {
                    if (propertyName == attribute.GetPropertyName())
                    {
                        found = true;

                        var setter = _tagHelperSetters.GetOrAdd(attribute.DisplayName, key =>
                        {
                            var propertyInfo   = tagHelperType.GetProperty(propertyName);
                            var propertySetter = propertyInfo.GetSetMethod();

                            var invokeType     = typeof(Action <,>).MakeGenericType(tagHelperType, propertyInfo.PropertyType);
                            var setterDelegate = Delegate.CreateDelegate(invokeType, propertySetter);

                            Action <ITagHelper, FluidValue> result = (h, v) =>
                            {
                                object value = null;

                                if (attribute.IsEnum)
                                {
                                    value = Enum.Parse(propertyInfo.PropertyType, v.ToStringValue());
                                }
                                else if (attribute.IsStringProperty)
                                {
                                    value = v.ToStringValue();
                                }
                                else if (propertyInfo.PropertyType == typeof(Boolean))
                                {
                                    value = Convert.ToBoolean(v.ToStringValue());
                                }
                                else
                                {
                                    value = v.ToObjectValue();
                                }

                                setterDelegate.DynamicInvoke(new[] { h, value });
                            };

                            return(result);
                        });

                        try
                        {
                            setter(tagHelper, arguments[name]);
                        }
                        catch (ArgumentException e)
                        {
                            throw new ArgumentException("Incorrect value type assigned to a tag.", name, e);
                        }

                        break;
                    }
                }

                if (!found)
                {
                    attributes.Add(new TagHelperAttribute(name.Replace("_", "-"), arguments[name].ToObjectValue()));
                }
            }

            var content = new StringWriter();

            if (Statements?.Any() ?? false)
            {
                Completion completion = Completion.Break;
                for (var index = 0; index < Statements.Count; index++)
                {
                    completion = await Statements[index].WriteToAsync(content, encoder, context);

                    if (completion != Completion.Normal)
                    {
                        return(completion);
                    }
                }
            }

            var tagHelperContext = new TagHelperContext(attributes,
                                                        new Dictionary <object, object>(), Guid.NewGuid().ToString("N"));

            var tagHelperOutput = new TagHelperOutput(helper, attributes, (_, e)
                                                      => Task.FromResult(new DefaultTagHelperContent().AppendHtml(content.ToString())));

            tagHelperOutput.Content.AppendHtml(content.ToString());
            await tagHelper.ProcessAsync(tagHelperContext, tagHelperOutput);

            tagHelperOutput.WriteTo(writer, HtmlEncoder.Default);

            return(Completion.Normal);
        }