예제 #1
0
        public async Task <string> RenderViewToStringAsync(string viewName, object model, IViewEngine viewEngine)
        {
            var actionContext = await GetActionContextAsync();

            var view = FindView(actionContext, viewName, viewEngine);

            using (var sb = StringBuilderPool.GetInstance())
            {
                using (var output = new StringWriter(sb.Builder))
                {
                    var viewContext = new ViewContext(
                        actionContext,
                        view,
                        new ViewDataDictionary(
                            metadataProvider: new EmptyModelMetadataProvider(),
                            modelState: new ModelStateDictionary())
                    {
                        Model = model
                    },
                        new TempDataDictionary(
                            actionContext.HttpContext,
                            _tempDataProvider),
                        output,
                        new HtmlHelperOptions());

                    await view.RenderAsync(viewContext);

                    await output.FlushAsync();
                }

                return(sb.Builder.ToString());
            }
        }
        protected async Task <bool> SendEmailAsync(string email, string subject, IShape model)
        {
            var body = string.Empty;

            using (var sb = StringBuilderPool.GetInstance())
            {
                using (var sw = new StringWriter(sb.Builder))
                {
                    var htmlContent = await _displayHelper.ShapeExecuteAsync(model);

                    htmlContent.WriteTo(sw, HtmlEncoder.Default);
                    body = sw.ToString();
                }
            }

            var message = new MailMessage()
            {
                To         = email,
                Subject    = subject,
                Body       = body,
                IsBodyHtml = true
            };

            var result = await _smtpService.SendAsync(message);

            return(result.Succeeded);
        }
예제 #3
0
        public override async Task <Completion> WriteToAsync(TextWriter writer, TextEncoder encoder, TemplateContext context)
        {
            var completion = Completion.Normal;

            using (var sb = StringBuilderPool.GetInstance())
            {
                using (var sw = new StringWriter(sb.Builder))
                {
                    for (var index = 0; index < Statements.Count; index++)
                    {
                        // Don't encode captured blocks
                        completion = await Statements[index].WriteToAsync(sw, NullEncoder.Default, context);

                        if (completion != Completion.Normal)
                        {
                            // Stop processing the block statements
                            // We return the completion to flow it to the outer loop
                            break;
                        }
                    }

                    context.SetValue(Identifier, sw.ToString());
                }
            }

            return(completion);
        }
예제 #4
0
        public override async ValueTask <Completion> WriteToAsync(TextWriter writer, TextEncoder encoder, TemplateContext context)
        {
            var completion = Completion.Normal;

            using var sb = StringBuilderPool.GetInstance();
            using var sw = new StringWriter(sb.Builder);
            for (var i = 0; i < _statements.Count; i++)
            {
                completion = await _statements[i].WriteToAsync(sw, encoder, context);

                if (completion != Completion.Normal)
                {
                    // Stop processing the block statements
                    // We return the completion to flow it to the outer loop
                    break;
                }
            }

            var result = sw.ToString();

            // Substitute the result if a custom callback is provided
            if (context.Captured != null)
            {
                result = await context.Captured.Invoke(Identifier, result);
            }

            // Don't encode captured blocks
            context.SetValue(Identifier, new StringValue(result, false));

            return(completion);
        }
        private StringBuilder AllocateBuilder()
        {
            _previousPooledBuilders ??= new List <StringBuilderPool>();
            _previousPooledBuilders.Add(_pooledBuilder);

            _pooledBuilder = StringBuilderPool.GetInstance();
            _builder       = _pooledBuilder.Builder;
            return(_builder);
        }
예제 #6
0
        private static string CreateQueryStringTokenKey(IEnumerable <string> values)
        {
            using var stringBuilderPool = StringBuilderPool.GetInstance();
            var result = stringBuilderPool.Builder;

            result.Append(TokenCacheKeyPrefix);
            foreach (var item in values)
            {
                result.Append(item);
            }
            return(result.ToString());
        }
예제 #7
0
        public void ShouldWriteMultipleBufferFragmentPages()
        {
            var buffer = new ViewBufferTextWriterContent();

            var capacity = StringBuilderPool.GetInstance().Builder.Capacity;

            buffer.Write(new String('x', capacity - 1).ToCharArray());
            buffer.Write(new String('x', 11).ToCharArray(), 1, 3);
            var result = Serialize(buffer);

            Assert.Equal(capacity + 2, result.Length);
        }
예제 #8
0
        public void ShouldWriteMultipleStringPages()
        {
            var buffer = new ViewBufferTextWriterContent();

            var capacity = StringBuilderPool.GetInstance().Builder.Capacity;
            var page     = new String('x', capacity);

            buffer.Write(page);
            buffer.Write(page);
            var result = Serialize(buffer);

            Assert.Equal(page + page, result);
        }
예제 #9
0
        public ContentItemType(IOptions <GraphQLContentOptions> optionsAccessor)
        {
            _options = optionsAccessor.Value;

            Name = "ContentItemType";

            Field(ci => ci.ContentItemId).Description("Content item id");
            Field(ci => ci.ContentItemVersionId).Description("The content item version id");
            Field(ci => ci.ContentType).Description("Type of content");
            Field(ci => ci.DisplayText).Description("The display text of the content item");
            Field(ci => ci.Published).Description("Is the published version");
            Field(ci => ci.Latest).Description("Is the latest version");
            Field <DateTimeGraphType>("modifiedUtc", resolve: ci => ci.Source.ModifiedUtc, description: "The date and time of modification");
            Field <DateTimeGraphType>("publishedUtc", resolve: ci => ci.Source.PublishedUtc, description: "The date and time of publication");
            Field <DateTimeGraphType>("createdUtc", resolve: ci => ci.Source.CreatedUtc, description: "The date and time of creation");
            Field(ci => ci.Owner).Description("The owner of the content item");
            Field(ci => ci.Author).Description("The author of the content item");

            Field <StringGraphType, string>()
            .Name("render")
            .ResolveLockedAsync(async context =>
            {
                var userContext     = (GraphQLContext)context.UserContext;
                var serviceProvider = userContext.ServiceProvider;

                // Build shape
                var displayManager      = serviceProvider.GetRequiredService <IContentItemDisplayManager>();
                var updateModelAccessor = serviceProvider.GetRequiredService <IUpdateModelAccessor>();
                var model = await displayManager.BuildDisplayAsync(context.Source, updateModelAccessor.ModelUpdater);

                var displayHelper = serviceProvider.GetRequiredService <IDisplayHelper>();
                var htmlEncoder   = serviceProvider.GetRequiredService <HtmlEncoder>();

                using (var sb = StringBuilderPool.GetInstance())
                {
                    using (var sw = new StringWriter(sb.Builder))
                    {
                        var htmlContent = await displayHelper.ShapeExecuteAsync(model);
                        htmlContent.WriteTo(sw, htmlEncoder);

                        await sw.FlushAsync();
                        return(sw.ToString());
                    }
                }
            });

            Interface <ContentItemInterface>();

            IsTypeOf = IsContentType;
        }
예제 #10
0
        public ValueTask <FluidValue> ProcessAsync(FluidValue input, FilterArguments arguments, TemplateContext context)
        {
            if (!context.AmbientValues.TryGetValue("Services", out var services))
            {
                throw new ArgumentException("Services missing while invoking 'console_log'");
            }

            var env = ((IServiceProvider)services).GetRequiredService <IHostEnvironment>();

            var content = input.ToObjectValue();

            if (content == null || env.IsProduction())
            {
                return(new ValueTask <FluidValue>(NilValue.Instance));
            }

            using (var sb = StringBuilderPool.GetInstance())
            {
                sb.Builder.Append("<script>console.log(");

                if (content is string stringContent)
                {
                    sb.Builder.Append("\"").Append(stringContent).Append("\"");
                }
                else if (content is JToken jTokenContent)
                {
                    sb.Builder.Append(jTokenContent.ToString());
                }
                else if (content is ContentItem contentItem)
                {
                    sb.Builder.Append(OrchardRazorHelperExtensions.ConvertContentItem(contentItem).ToString());
                }
                else if (content is IShape shape)
                {
                    sb.Builder.Append(shape.ShapeToJson().ToString());
                }
                else
                {
                    sb.Builder.Append(JsonConvert.SerializeObject(content));
                }

                sb.Builder.Append(")</script>");

                var result = new StringValue(sb.Builder.ToString(), false);

                return(new ValueTask <FluidValue>(result));
            }
        }
예제 #11
0
        private async Task <string> EvaluateStatementsAsync(TextEncoder encoder, TemplateContext context)
        {
            using (var sb = StringBuilderPool.GetInstance())
            {
                using (var content = new StringWriter(sb.Builder))
                {
                    foreach (var statement in Statements)
                    {
                        await statement.WriteToAsync(content, encoder, context);
                    }

                    await content.FlushAsync();
                }

                return(sb.Builder.ToString());
            }
        }
예제 #12
0
        public async Task DisplayedAsync(ShapeDisplayContext context)
        {
            var cacheContext = context.ShapeMetadata.Cache();

            // If the shape is not configured to be cached, continue as usual
            if (cacheContext == null)
            {
                if (context.ChildContent == null)
                {
                    context.ChildContent = HtmlString.Empty;
                }

                return;
            }

            // If we have got this far, then this shape is configured to be cached.
            // We need to determine whether or not the ChildContent of this shape was retrieved from the cache by the DisplayingAsync method above, as opposed to generated by the View Engine.
            // ChildContent will be generated by the View Engine if it was not available in the cache when we rendered the shape.
            // In this instance, we need insert the ChildContent into the cache so that subsequent attempt to render this shape can take advantage of the cached content.

            // If the ChildContent was retrieved form the cache, then the Cache Context will be present in the _cached collection (see the DisplayingAsync method in this class).
            // So, if the cache context is not present in the _cached collection, we need to insert the ChildContent value into the cache:
            if (!_cached.ContainsKey(cacheContext.CacheId) && context.ChildContent != null)
            {
                // The content is pre-encoded in the cache so we don't have to do it every time it's rendered
                using (var sb = StringBuilderPool.GetInstance())
                {
                    using (var sw = new StringWriter(sb.Builder))
                    {
                        context.ChildContent.WriteTo(sw, HtmlEncoder.Default);
                        await _dynamicCacheService.SetCachedValueAsync(cacheContext, sw.ToString());

                        await sw.FlushAsync();
                    }
                }
            }
        }
예제 #13
0
        /// <summary>
        /// Gets the formatted message string.
        /// </summary>
        /// <param name="message">the error message</param>
        /// <param name="devMsg">the developer's message</param>
        /// <returns></returns>
        private static String GetMessageString(ErrorMessage message, string devMsg)
        {
            PooledStringBuilder sb = StringBuilderPool.GetInstance().GetStringBuilder();

            try
            {
                sb.Append("ErrorMessage [");
                sb.Append(message);
                sb.Append("user_message = ");
                sb.Append(message.GetUserMessage());
                sb.Append(", developer_message = ");
                sb.Append(devMsg);
                sb.Append("]");
            }
            catch (PooledException e)
            {
                // TODO Auto-generated catch block
                Console.WriteLine(e.ToString());
            }
            String s = sb.ToString();

            sb.ReturnToPool();
            return(s);
        }
예제 #14
0
        public static async ValueTask <Completion> WriteToAsync(List <FilterArgument> arguments, IReadOnlyList <Statement> statements, TextWriter writer, TextEncoder encoder, TemplateContext context)
        {
            var services = ((LiquidTemplateContext)context).Services;

            var dynamicCache      = services.GetService <IDynamicCacheService>();
            var cacheScopeManager = services.GetService <ICacheScopeManager>();
            var loggerFactory     = services.GetService <ILoggerFactory>();
            var logger            = loggerFactory.CreateLogger <CacheTag>();
            var cacheOptions      = services.GetRequiredService <IOptions <CacheOptions> >().Value;

            if (dynamicCache == null || cacheScopeManager == null)
            {
                logger.LogInformation(@"Liquid cache block entered without an available IDynamicCacheService or ICacheScopeManager.
                                        The contents of the cache block will not be cached.
                                        To enable caching, make sure that a feature that contains an implementation of IDynamicCacheService and ICacheScopeManager is enabled (for example, 'Dynamic Cache').");

                if (statements != null && statements.Count > 0)
                {
                    var completion = await statements.RenderStatementsAsync(writer, encoder, context);

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

                return(Completion.Normal);
            }

            var filterArguments = new FilterArguments();

            foreach (var argument in arguments)
            {
                filterArguments.Add(argument.Name, await argument.Expression.EvaluateAsync(context));
            }

            var cacheKey              = filterArguments.At(0).ToStringValue();
            var contexts              = filterArguments["vary_by"].ToStringValue();
            var tags                  = filterArguments["dependencies"].ToStringValue();
            var durationString        = filterArguments["expires_after"].ToStringValue();
            var slidingDurationString = filterArguments["expires_sliding"].ToStringValue();

            var cacheContext = new CacheContext(cacheKey)
                               .AddContext(contexts.Split(SplitChars, StringSplitOptions.RemoveEmptyEntries))
                               .AddTag(tags.Split(SplitChars, StringSplitOptions.RemoveEmptyEntries));

            if (TimeSpan.TryParse(durationString, out var duration))
            {
                cacheContext.WithExpiryAfter(duration);
            }

            if (TimeSpan.TryParse(slidingDurationString, out var slidingDuration))
            {
                cacheContext.WithExpirySliding(slidingDuration);
            }

            var cacheResult = await dynamicCache.GetCachedValueAsync(cacheContext);

            if (cacheResult != null)
            {
                await writer.WriteAsync(cacheResult);

                return(Completion.Normal);
            }

            cacheScopeManager.EnterScope(cacheContext);

            var content = "";

            try
            {
                if (statements != null && statements.Count > 0)
                {
                    using var sb = StringBuilderPool.GetInstance();
                    using (var render = new StringWriter(sb.Builder))
                    {
                        foreach (var statement in statements)
                        {
                            await statement.WriteToAsync(render, encoder, context);
                        }

                        await render.FlushAsync();
                    }

                    content = sb.Builder.ToString();
                }
            }
            finally
            {
                cacheScopeManager.ExitScope();
            }

            if (cacheOptions.DebugMode)
            {
                // No need to optimize this code as it will be used for debugging purpose.
                var debugContent = new StringWriter();
                debugContent.WriteLine();
                debugContent.WriteLine($"<!-- CACHE BLOCK: {cacheContext.CacheId} ({Guid.NewGuid()})");
                debugContent.WriteLine($"         VARY BY: {String.Join(", ", cacheContext.Contexts)}");
                debugContent.WriteLine($"    DEPENDENCIES: {String.Join(", ", cacheContext.Tags)}");
                debugContent.WriteLine($"      EXPIRES ON: {cacheContext.ExpiresOn}");
                debugContent.WriteLine($"   EXPIRES AFTER: {cacheContext.ExpiresAfter}");
                debugContent.WriteLine($" EXPIRES SLIDING: {cacheContext.ExpiresSliding}");
                debugContent.WriteLine("-->");

                debugContent.WriteLine(content);

                debugContent.WriteLine();
                debugContent.WriteLine($"<!-- END CACHE BLOCK: {cacheContext.CacheId} -->");

                content = debugContent.ToString();
            }

            await dynamicCache.SetCachedValueAsync(cacheContext, content);

            await writer.WriteAsync(content);

            return(Completion.Normal);
        }
예제 #15
0
        public override async ValueTask <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;

            var viewContextAccessor = services.GetRequiredService <ViewContextAccessor>();
            var viewContext         = viewContextAccessor.ViewContext;

            var arguments = (FilterArguments)(await _arguments.EvaluateAsync(context)).ToObjectValue();
            var helper    = _helper ?? arguments["helper_name"].Or(arguments.At(0)).ToStringValue();

            var factory = services.GetRequiredService <LiquidTagHelperFactory>();

            // Each tag is a singleton, as views are
            if (_activator == null)
            {
                lock (this)
                {
                    if (_activator == null)
                    {
                        _activator = factory.GetActivator(helper, arguments.Names);
                    }
                }
            }

            if (_activator == LiquidTagHelperActivator.None)
            {
                return(Completion.Normal);
            }

            var tagHelper = factory.CreateTagHelper(_activator, (ViewContext)viewContext,
                                                    arguments, out var contextAttributes, out var outputAttributes);

            var content = "";

            // Build the ChildContent of this tag
            using (var sb = StringBuilderPool.GetInstance())
            {
                using (var output = new StringWriter(sb.Builder))
                {
                    if (Statements != null && Statements.Count > 0)
                    {
                        var completion = Completion.Break;

                        for (var index = 0; index < Statements.Count; index++)
                        {
                            completion = await Statements[index].WriteToAsync(output, encoder, context);

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

                    await output.FlushAsync();
                }

                content = sb.Builder.ToString();
            }

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

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

            tagHelperOutput.Content.AppendHtml(content);

            await tagHelper.ProcessAsync(tagHelperContext, tagHelperOutput);

            tagHelperOutput.WriteTo(writer, HtmlEncoder.Default);

            return(Completion.Normal);
        }
예제 #16
0
        public static ValueTask <FluidValue> Date(FluidValue input, FilterArguments arguments, TemplateContext context)
        {
            if (!TryGetDateTimeInput(input, context, out var value))
            {
                return(NilValue.Instance);
            }

            if (arguments.At(0).IsNil())
            {
                return(NilValue.Instance);
            }

            var format = arguments.At(0).ToStringValue();

            using (var sb = StringBuilderPool.GetInstance())
            {
                var result = sb.Builder;

                ForStrf(value, format, result);

                return(new StringValue(result.ToString()));
            }

            void ForStrf(DateTimeOffset value, string format, StringBuilder result)
            {
                var percent = false;

                var removeLeadingZerosFlag       = false;
                var useSpaceForPaddingFlag       = false;
                var upperCaseFlag                = false;
                var useColonsForZeeDirectiveFlag = false;

                for (var i = 0; i < format.Length; i++)
                {
                    var c = format[i];
                    if (!percent)
                    {
                        if (c == '%')
                        {
                            percent = true;
                        }
                        else
                        {
                            result.Append(c);
                        }
                    }
                    else
                    {
                        switch (c)
                        {
                        case '^': upperCaseFlag = true; continue;

                        case '-': removeLeadingZerosFlag = true; continue;

                        case '_': useSpaceForPaddingFlag = true; continue;

                        case ':': useColonsForZeeDirectiveFlag = true; continue;

                        case 'a':
                            string AbbreviatedDayName() => context.CultureInfo.DateTimeFormat.AbbreviatedDayNames[(int)value.DayOfWeek];

                            var abbreviatedDayName = AbbreviatedDayName();
                            result.Append(upperCaseFlag ? abbreviatedDayName.ToUpper() : abbreviatedDayName);
                            break;

                        case 'A':
                        {
                            var dayName = context.CultureInfo.DateTimeFormat.DayNames[(int)value.DayOfWeek];
                            result.Append(upperCaseFlag ? dayName.ToUpper() : dayName);
                            break;
                        }

                        case 'b':
                            var abbreviatedMonthName = context.CultureInfo.DateTimeFormat.AbbreviatedMonthNames[value.Month - 1];
                            result.Append(upperCaseFlag ? abbreviatedMonthName.ToUpper() : abbreviatedMonthName);
                            break;

                        case 'B':
                        {
                            var monthName = context.CultureInfo.DateTimeFormat.MonthNames[value.Month - 1];
                            result.Append(upperCaseFlag ? monthName.ToUpper() : monthName);
                            break;
                        }

                        case 'c':
                        {
                            // c is defined as "%a %b %e %T %Y" but it's also supposed to be locale aware, so we are using the
                            // C# standard format instead
                            result.Append(upperCaseFlag ? value.ToString("F", context.CultureInfo).ToUpper() : value.ToString("F", context.CultureInfo));
                            break;
                        }

                        case 'C': result.Append(value.Year / 100); break;

                        case 'd':
                        {
                            var day = value.Day.ToString(context.CultureInfo);
                            if (useSpaceForPaddingFlag)
                            {
                                result.Append(day.PadLeft(2, ' '));
                            }
                            else if (removeLeadingZerosFlag)
                            {
                                result.Append(day);
                            }
                            else
                            {
                                result.Append(day.PadLeft(2, '0'));
                            }
                            break;
                        }

                        case 'D':
                        {
                            var sb = new StringBuilder();
                            ForStrf(value, "%m/%d/%y", sb);
                            result.Append(upperCaseFlag ? sb.ToString().ToUpper() : sb.ToString());
                            break;
                        }

                        case 'e':
                            result.Append(value.Day.ToString(context.CultureInfo).PadLeft(2, ' '));
                            break;

                        case 'F':
                        {
                            var sb = new StringBuilder();
                            ForStrf(value, "%Y-%m-%d", sb);
                            result.Append(upperCaseFlag ? sb.ToString().ToUpper() : sb.ToString());
                            break;
                        }

                        case 'H':
                            result.Append(value.ToString("HH"));
                            break;

                        case 'I': result.Append((value.Hour % 12).ToString(context.CultureInfo).PadLeft(2, '0')); break;

                        case 'j': result.Append(value.DayOfYear.ToString(context.CultureInfo).PadLeft(3, '0')); break;

                        case 'k': result.Append(value.Hour); break;

                        case 'l': result.Append(value.ToString("%h", context.CultureInfo).PadLeft(2, ' ')); break;

                        case 'L': result.Append(value.Millisecond.ToString(context.CultureInfo).PadLeft(3, '0')); break;

                        case 'm':
                        {
                            var month = value.Month.ToString(context.CultureInfo);
                            if (useSpaceForPaddingFlag)
                            {
                                result.Append(month.PadLeft(2, ' '));
                            }
                            else if (removeLeadingZerosFlag)
                            {
                                result.Append(month);
                            }
                            else
                            {
                                result.Append(month.PadLeft(2, '0'));
                            }
                            break;
                        }

                        case 'M':
                            result.Append(value.Minute.ToString(context.CultureInfo).PadLeft(2, '0'));
                            break;

                        case 'p': result.Append(value.ToString("tt", context.CultureInfo).ToUpper()); break;

                        case 'P': result.Append(value.ToString("tt", context.CultureInfo).ToLower()); break;

                        case 'r':
                        {
                            var sb = new StringBuilder();
                            ForStrf(value, "%I:%M:%S %p", sb);
                            result.Append(upperCaseFlag ? sb.ToString().ToUpper() : sb.ToString());
                            break;
                        }

                        case 'R':
                        {
                            var sb = new StringBuilder();
                            ForStrf(value, "%H:%M", sb);
                            result.Append(upperCaseFlag ? sb.ToString().ToUpper() : sb.ToString());
                            break;
                        }

                        case 's': result.Append(value.ToUnixTimeSeconds()); break;

                        case 'S':
                            result.Append(value.Second.ToString(context.CultureInfo).PadLeft(2, '0'));
                            break;

                        case 'x':
                        {
                            // x is defined as "%m/%d/%y" but it's also supposed to be locale aware, so we are using the
                            // C# short date pattern standard format instead

                            result.Append(upperCaseFlag ? value.ToString("d", context.CultureInfo).ToUpper() : value.ToString("d", context.CultureInfo));
                            break;
                        }

                        case 'X':
                        {
                            // X is defined as "%T" but it's also supposed to be locale aware, so we are using the
                            // C# short time pattern standard format instead

                            result.Append(upperCaseFlag ? value.ToString("t", context.CultureInfo).ToUpper() : value.ToString("t", context.CultureInfo));
                            break;
                        }

                        case 'T':
                        {
                            var sb = new StringBuilder();
                            ForStrf(value, "%H:%M:%S", sb);
                            result.Append(upperCaseFlag ? sb.ToString().ToUpper() : sb.ToString());
                            break;
                        }

                        case 'u': result.Append((int)value.DayOfWeek); break;

                        case 'U': result.Append(context.CultureInfo.Calendar.GetWeekOfYear(value.DateTime, CalendarWeekRule.FirstDay, DayOfWeek.Sunday).ToString().PadLeft(2, '0')); break;

                        case 'v':
                        {
                            var sb = new StringBuilder();
                            ForStrf(value, "%e-%b-%Y", sb);
                            result.Append(upperCaseFlag ? sb.ToString().ToUpper() : sb.ToString());
                            break;
                        }

                        case 'V': result.Append((value.DayOfYear / 7 + 1).ToString(context.CultureInfo).PadLeft(2, '0')); break;

                        case 'W': result.Append(context.CultureInfo.Calendar.GetWeekOfYear(value.DateTime, CalendarWeekRule.FirstDay, DayOfWeek.Monday).ToString().PadLeft(2, '0')); break;

                        case 'y':
                            result.Append(value.Year % 100);
                            break;

                        case 'Y':
                            result.Append(value.Year.ToString().PadLeft(4, '0'));
                            break;

                        case 'z':
                        {
                            var zzz = value.ToString("zzz", context.CultureInfo);
                            result.Append(useColonsForZeeDirectiveFlag ? zzz : zzz.Replace(":", ""));
                            break;
                        }

                        case 'Z':
                            result.Append(value.ToString("zzz", context.CultureInfo));
                            break;

                        case '%': result.Append('%'); break;

                        case '+':
                        {
                            var sb = new StringBuilder();
                            ForStrf(value, "%a %b %e %H:%M:%S %Z %Y", sb);
                            result.Append(upperCaseFlag ? sb.ToString().ToUpper() : sb.ToString());
                            break;
                        }

                        default: result.Append('%').Append(c); break;
                        }

                        percent = false;
                        removeLeadingZerosFlag       = false;
                        useSpaceForPaddingFlag       = false;
                        upperCaseFlag                = false;
                        useColonsForZeeDirectiveFlag = false;
                    }
                }
            }
        }
예제 #17
0
        public static FluidValue Date(FluidValue input, FilterArguments arguments, TemplateContext context)
        {
            if (!TryGetDateTimeInput(input, context, out var value))
            {
                return(NilValue.Instance);
            }

            if (arguments.At(0).IsNil())
            {
                return(NilValue.Instance);
            }

            var format = arguments.At(0).ToStringValue();

            using (var sb = StringBuilderPool.GetInstance())
            {
                sb.Builder.EnsureCapacity(format.Length * 2);
                var result  = sb.Builder;
                var percent = false;

                for (var i = 0; i < format.Length; i++)
                {
                    var c = format[i];
                    if (!percent)
                    {
                        if (c == '%')
                        {
                            percent = true;
                        }
                        else
                        {
                            result.Append(c);
                        }
                    }
                    else
                    {
                        switch (c)
                        {
                        case 'a': result.Append(context.CultureInfo.DateTimeFormat.AbbreviatedDayNames[(int)value.DayOfWeek]); break;

                        case 'A': result.Append(context.CultureInfo.DateTimeFormat.DayNames[(int)value.DayOfWeek]); break;

                        case 'b': result.Append(context.CultureInfo.DateTimeFormat.AbbreviatedMonthNames[value.Month - 1]); break;

                        case 'B': result.Append(context.CultureInfo.DateTimeFormat.MonthNames[value.Month - 1]); break;

                        case 'c': result.Append(value.ToString("F", context.CultureInfo)); break;

                        case 'C': result.Append(value.Year / 100); break;

                        case 'd': result.Append(value.Day.ToString(context.CultureInfo).PadLeft(2, '0')); break;

                        case 'D': result.Append(value.ToString("d", context.CultureInfo)); break;

                        case 'e': result.Append(value.Day.ToString(context.CultureInfo).PadLeft(2, ' ')); break;

                        case 'F': result.Append(value.ToString("yyyy-MM-dd", context.CultureInfo)); break;

                        case 'H': result.Append(value.Hour.ToString(context.CultureInfo).PadLeft(2, '0')); break;

                        case 'I': result.Append((value.Hour % 12).ToString(context.CultureInfo).PadLeft(2, '0')); break;

                        case 'j': result.Append(value.DayOfYear.ToString(context.CultureInfo).PadLeft(3, '0')); break;

                        case 'k': result.Append(value.Hour); break;

                        case 'l': result.Append((value.Hour % 12).ToString(context.CultureInfo).PadLeft(2, ' ')); break;

                        case 'L': result.Append(value.Millisecond.ToString(context.CultureInfo).PadLeft(3, '0')); break;

                        case 'm': result.Append(value.Month.ToString(context.CultureInfo).PadLeft(2, '0')); break;

                        case 'M': result.Append(value.Minute.ToString(context.CultureInfo).PadLeft(2, '0')); break;

                        case 'p': result.Append(value.ToString("tt", context.CultureInfo).ToUpper()); break;

                        case 'P': result.Append(value.ToString("tt", context.CultureInfo).ToLower()); break;

                        case 'T':
                        case 'r': result.Append(value.ToString("T", context.CultureInfo).ToUpper()); break;

                        case 'R': result.Append(value.ToString("t", context.CultureInfo).ToUpper()); break;

                        case 's': result.Append(value.ToUnixTimeSeconds()); break;

                        case 'S': result.Append(value.Second.ToString(context.CultureInfo).PadLeft(2, '0')); break;

                        case 'u': result.Append((int)value.DayOfWeek); break;

                        case 'U': result.Append(context.CultureInfo.Calendar.GetWeekOfYear(value.DateTime, CalendarWeekRule.FirstDay, DayOfWeek.Sunday).ToString().PadLeft(2, '0')); break;

                        case 'v': result.Append(value.ToString("D", context.CultureInfo)); break;

                        case 'V': result.Append((value.DayOfYear / 7 + 1).ToString(context.CultureInfo).PadLeft(2, '0')); break;

                        case 'W': result.Append(context.CultureInfo.Calendar.GetWeekOfYear(value.DateTime, CalendarWeekRule.FirstDay, DayOfWeek.Monday).ToString().PadLeft(2, '0')); break;

                        case 'y': result.Append(value.ToString("yy", context.CultureInfo)); break;

                        case 'Y': result.Append(value.Year); break;

                        case 'z': result.Append(value.ToString("zzz", context.CultureInfo)); break;

                        case 'Z': goto default;     // unsupported

                        case '%': result.Append('%'); break;

                        default: result.Append('%').Append(c); break;
                        }

                        percent = false;
                    }
                }

                return(new StringValue(result.ToString()));
            }
        }
        public override async Task <IDisplayResult> EditAsync(ContentOptionsViewModel model, IUpdateModel updater)
        {
            var settings = (await _siteService.GetSiteSettingsAsync()).As <TaxonomyContentsAdminListSettings>();

            if (!settings.TaxonomyContentItemIds.Any())
            {
                return(null);
            }

            var results    = new List <IDisplayResult>();
            var taxonomies = await _contentManager.GetAsync(settings.TaxonomyContentItemIds);

            var position = 5;

            foreach (var taxonomy in taxonomies)
            {
                results.Add(
                    Initialize <TaxonomyContentsAdminFilterViewModel>("ContentsAdminList__TaxonomyFilter", m =>
                {
                    var termEntries = new List <FilterTermEntry>();
                    PopulateTermEntries(termEntries, taxonomy.As <TaxonomyPart>().Terms, 0);
                    var terms = new List <SelectListItem>
                    {
                        new SelectListItem()
                        {
                            Text = S["Clear filter"], Value = ""
                        },
                        new SelectListItem()
                        {
                            Text = S["Show all"], Value = "Taxonomy:" + taxonomy.ContentItemId
                        }
                    };

                    foreach (var term in termEntries)
                    {
                        using var sb = StringBuilderPool.GetInstance();
                        for (var l = 0; l < term.Level; l++)
                        {
                            sb.Builder.Insert(0, LevelPadding);
                        }
                        sb.Builder.Append(term.DisplayText);
                        var item = new SelectListItem()
                        {
                            Text = sb.Builder.ToString(), Value = "Term:" + term.ContentItemId
                        };
                        terms.Add(item);
                    }

                    m.DisplayText = taxonomy.DisplayText;
                    m.Taxonomies  = terms;
                })
                    .Location("Actions:40." + position.ToString())
                    .Prefix("Taxonomy" + taxonomy.ContentItemId)
                    );

                position += 5;
            }

            if (results.Any())
            {
                return(Combine(results));
            }

            return(null);
        }
예제 #19
0
        public static FluidValue Date(FluidValue input, FilterArguments arguments, TemplateContext context)
        {
            if (!TryGetDateTimeInput(input, context, out var value))
            {
                return(NilValue.Instance);
            }

            if (arguments.At(0).IsNil())
            {
                return(NilValue.Instance);
            }

            var format = arguments.At(0).ToStringValue();

            using (var sb = StringBuilderPool.GetInstance())
            {
                sb.Builder.EnsureCapacity(format.Length * 2);
                var result  = sb.Builder;
                var percent = false;

                var removeLeadingZerosFlag       = false;
                var useSpaceForPaddingFlag       = false;
                var upperCaseFlag                = false;
                var useColonsForZeeDirectiveFlag = false;

                for (var i = 0; i < format.Length; i++)
                {
                    var c = format[i];
                    if (!percent)
                    {
                        if (c == '%')
                        {
                            percent = true;
                        }
                        else
                        {
                            result.Append(c);
                        }
                    }
                    else
                    {
                        switch (c)
                        {
                        case '^': upperCaseFlag = true; continue;

                        case '-': removeLeadingZerosFlag = true; continue;

                        case '_': useSpaceForPaddingFlag = true; continue;

                        case ':': useColonsForZeeDirectiveFlag = true; continue;

                        case 'a':
                        {
                            var abbreviatedDayName = context.CultureInfo.DateTimeFormat.AbbreviatedDayNames[(int)value.DayOfWeek];
                            result.Append(upperCaseFlag ? abbreviatedDayName.ToUpper() : abbreviatedDayName);
                            break;
                        }

                        case 'A':
                        {
                            var dayName = context.CultureInfo.DateTimeFormat.DayNames[(int)value.DayOfWeek];
                            result.Append(upperCaseFlag ? dayName.ToUpper() : dayName);
                            break;
                        }

                        case 'b':
                        {
                            var abbreviatedMonthName = context.CultureInfo.DateTimeFormat.AbbreviatedMonthNames[value.Month - 1];
                            result.Append(upperCaseFlag ? abbreviatedMonthName.ToUpper() : abbreviatedMonthName);
                            break;
                        }

                        case 'B':
                        {
                            var monthName = context.CultureInfo.DateTimeFormat.MonthNames[value.Month - 1];
                            result.Append(upperCaseFlag ? monthName.ToUpper() : monthName);
                            break;
                        }

                        case 'c':
                        {
                            var f = value.ToString("F", context.CultureInfo);
                            result.Append(upperCaseFlag ? f.ToUpper() : f);
                            break;
                        }

                        case 'C': result.Append(value.Year / 100); break;

                        case 'd':
                        {
                            var day = value.Day.ToString(context.CultureInfo);
                            if (useSpaceForPaddingFlag)
                            {
                                result.Append(day.PadLeft(2, ' '));
                            }
                            else if (removeLeadingZerosFlag)
                            {
                                result.Append(day);
                            }
                            else
                            {
                                result.Append(day.PadLeft(2, '0'));
                            }
                            break;
                        }

                        case 'D': result.Append(value.ToString("d", context.CultureInfo)); break;

                        case 'e': result.Append(value.Day.ToString(context.CultureInfo).PadLeft(2, ' ')); break;

                        case 'F': result.Append(value.ToString("yyyy-MM-dd", context.CultureInfo)); break;

                        case 'H': result.Append(value.Hour.ToString(context.CultureInfo).PadLeft(2, '0')); break;

                        case 'I': result.Append((value.Hour % 12).ToString(context.CultureInfo).PadLeft(2, '0')); break;

                        case 'j': result.Append(value.DayOfYear.ToString(context.CultureInfo).PadLeft(3, '0')); break;

                        case 'k': result.Append(value.Hour); break;

                        case 'l': result.Append(value.ToString("%h", context.CultureInfo).PadLeft(2, ' ')); break;

                        case 'L': result.Append(value.Millisecond.ToString(context.CultureInfo).PadLeft(3, '0')); break;

                        case 'm':
                        {
                            var month = value.Month.ToString(context.CultureInfo);
                            if (useSpaceForPaddingFlag)
                            {
                                result.Append(month.PadLeft(2, ' '));
                            }
                            else if (removeLeadingZerosFlag)
                            {
                                result.Append(month);
                            }
                            else
                            {
                                result.Append(month.PadLeft(2, '0'));
                            }
                            break;
                        }

                        case 'M': result.Append(value.Minute.ToString(context.CultureInfo).PadLeft(2, '0')); break;

                        case 'p': result.Append(value.ToString("tt", context.CultureInfo).ToUpper()); break;

                        case 'P': result.Append(value.ToString("tt", context.CultureInfo).ToLower()); break;

                        case 'T':
                        case 'r': result.Append(value.ToString("T", context.CultureInfo).ToUpper()); break;

                        case 'R': result.Append(value.ToString("t", context.CultureInfo).ToUpper()); break;

                        case 's': result.Append(value.ToUnixTimeSeconds()); break;

                        case 'S': result.Append(value.Second.ToString(context.CultureInfo).PadLeft(2, '0')); break;

                        case 'u': result.Append((int)value.DayOfWeek); break;

                        case 'U': result.Append(context.CultureInfo.Calendar.GetWeekOfYear(value.DateTime, CalendarWeekRule.FirstDay, DayOfWeek.Sunday).ToString().PadLeft(2, '0')); break;

                        case 'v':
                        {
                            var d = value.ToString("D", context.CultureInfo);
                            result.Append(upperCaseFlag ? d.ToUpper() : d);
                            break;
                        }

                        case 'V': result.Append((value.DayOfYear / 7 + 1).ToString(context.CultureInfo).PadLeft(2, '0')); break;

                        case 'W': result.Append(context.CultureInfo.Calendar.GetWeekOfYear(value.DateTime, CalendarWeekRule.FirstDay, DayOfWeek.Monday).ToString().PadLeft(2, '0')); break;

                        case 'y': result.Append(value.ToString("yy", context.CultureInfo)); break;

                        case 'Y': result.Append(value.Year); break;

                        case 'z':
                        {
                            var zzz = value.ToString("zzz", context.CultureInfo);
                            result.Append(useColonsForZeeDirectiveFlag ? zzz : zzz.Replace(":", ""));
                            break;
                        }

                        case 'Z':
                            result.Append(value.ToString("zzz", context.CultureInfo));
                            break;

                        case '%': result.Append('%'); break;

                        default: result.Append('%').Append(c); break;
                        }

                        percent = false;
                        removeLeadingZerosFlag       = false;
                        useSpaceForPaddingFlag       = false;
                        upperCaseFlag                = false;
                        useColonsForZeeDirectiveFlag = false;
                    }
                }

                return(new StringValue(result.ToString()));
            }
        }
예제 #20
0
        public ValueTask <string> ProcessAsync(string text)
        {
            if (string.IsNullOrEmpty(text))
            {
                return(new ValueTask <string>(string.Empty));
            }

            // optimize code path if nothing to do
            // if it doesn't have [media] and [/media]
            // or doesn't have [image] and [/image]

            var hasMediaCode = text.Contains("[media]", StringComparison.OrdinalIgnoreCase) &&
                               text.Contains("[/media]", StringComparison.OrdinalIgnoreCase);

            var hasImageCode = text.Contains("[image]", StringComparison.OrdinalIgnoreCase) &&
                               text.Contains("[/image]", StringComparison.OrdinalIgnoreCase);


            if (!hasMediaCode && !hasImageCode)
            {
                return(new ValueTask <string>(text));
            }

            using (var sb = StringBuilderPool.GetInstance())
            {
                sb.Builder.Append(text);

                var index = -1;
                // When acting recursively track the modifications to the string builder start index.
                var modifierIndex = 0;
                var allIndices    = new List <int>();

                // For backwards compatability check for [media]
                // This code can be removed in a future version.
                // [media]
                if (hasMediaCode)
                {
                    while (-1 != (index = text.IndexOf("[media]", index + 1, StringComparison.Ordinal)))
                    {
                        allIndices.Add(index);
                    }

                    foreach (var start in allIndices)
                    {
                        var end = text.IndexOf("[/media]", start, StringComparison.Ordinal);

                        if (end == -1)
                        {
                            continue;
                        }

                        modifierIndex = SubstituteTag(text, sb, start, modifierIndex, end);
                    }
                }

                // [image]
                if (hasImageCode)
                {
                    index = -1;
                    allIndices.Clear();
                    while (-1 != (index = text.IndexOf("[image]", index + 1, StringComparison.Ordinal)))
                    {
                        allIndices.Add(index);
                    }

                    foreach (var start in allIndices)
                    {
                        var end = text.IndexOf("[/image]", start + modifierIndex, StringComparison.Ordinal);

                        if (end == -1)
                        {
                            continue;
                        }

                        modifierIndex += SubstituteTag(text, sb, start, modifierIndex, end);
                    }
                }

                return(new ValueTask <string>(sb.ToString()));
            }
        }
        public async Task <IHtmlContent> ProcessContentAsync(TagHelperOutput output, CacheContext cacheContext)
        {
            IHtmlContent content = null;

            while (content == null)
            {
                Task <IHtmlContent> result;

                // Is there any request already processing the value?
                if (!_dynamicCacheTagHelperService.Workers.TryGetValue(CacheId, out result))
                {
                    // There is a small race condition here between TryGetValue and TryAdd that might cause the
                    // content to be computed more than once. We don't care about this race as the probability of
                    // happening is very small and the impact is not critical.
                    var tcs = new TaskCompletionSource <IHtmlContent>();

                    _dynamicCacheTagHelperService.Workers.TryAdd(CacheId, tcs.Task);

                    try
                    {
                        var value = await _dynamicCacheService.GetCachedValueAsync(cacheContext);

                        if (value == null)
                        {
                            // The value is not cached, we need to render the tag helper output
                            var processedContent = await output.GetChildContentAsync();

                            using (var sb = StringBuilderPool.GetInstance())
                            {
                                using (var writer = new StringWriter(sb.Builder))
                                {
                                    processedContent.WriteTo(writer, HtmlEncoder);
                                    await writer.FlushAsync();
                                }

                                var html = sb.Builder.ToString();

                                var formattingContext = new DistributedCacheTagHelperFormattingContext
                                {
                                    Html = new HtmlString(html)
                                };

                                await _dynamicCacheService.SetCachedValueAsync(cacheContext, html);

                                content = formattingContext.Html;
                            }
                        }
                        else
                        {
                            content = new HtmlString(value);
                        }
                    }
                    catch
                    {
                        content = null;
                        throw;
                    }
                    finally
                    {
                        // Remove the worker task before setting the result.
                        // If the result is null, other threads would potentially
                        // acquire it otherwise.
                        _dynamicCacheTagHelperService.Workers.TryRemove(CacheId, out result);

                        // Notify all other awaiters to render the content
                        tcs.TrySetResult(content);
                    }
                }
                else
                {
                    content = await result;
                }
            }

            return(content);
        }
예제 #22
0
 /// <summary>
 /// Gets a StringBuilder instance from a common object pool.
 /// </summary>
 /// <remarks>
 /// You are expected to call the Dispose method on the returned PooledObjectWrapper instance
 /// when you are done with the StringBuilder. Calling Dispose returns the StringBuilder to the
 /// pool.
 /// </remarks>
 public static PooledObjectWrapper <StringBuilder> GetStringBuilder()
 {
     return(StringBuilderPool.GetInstance());
 }
예제 #23
0
        public override async ValueTask <Completion> WriteToAsync(TextWriter writer, TextEncoder encoder, TemplateContext context)
        {
            // Evaluate all default values only once
            var defaultValues = new Dictionary <string, FluidValue>();

            for (var i = 0; i < Arguments.Count; i++)
            {
                var argument = Arguments[i];
                defaultValues[argument.Name] = argument.Expression == null ? NilValue.Instance : await argument.Expression.EvaluateAsync(context);
            }

            var f = new FunctionValue(async(args, c) =>
            {
                using var sb = StringBuilderPool.GetInstance();
                using var sw = new StringWriter(sb.Builder);

                context.EnterChildScope();

                try
                {
                    // Initialize the local context with the default values
                    foreach (var a in defaultValues)
                    {
                        context.SetValue(a.Key, a.Value);
                    }

                    var namedArguments = false;

                    // Apply all arguments from the invocation.
                    // As soon as a named argument is used, all subsequent ones need a name too.

                    for (var i = 0; i < args.Count; i++)
                    {
                        var positionalName = Arguments[i].Name;

                        namedArguments |= args.HasNamed(positionalName);

                        if (!namedArguments)
                        {
                            context.SetValue(positionalName, args.At(i));
                        }
                        else
                        {
                            context.SetValue(positionalName, args[positionalName]);
                        }
                    }

                    for (var i = 0; i < _statements.Count; i++)
                    {
                        var completion = await _statements[i].WriteToAsync(sw, encoder, context);

                        if (completion != Completion.Normal)
                        {
                            // Stop processing the block statements
                            // We return the completion to flow it to the outer loop
                            break;
                        }
                    }

                    var result = sw.ToString();

                    // Don't encode the result
                    return(new StringValue(result, false));
                }
                finally
                {
                    context.ReleaseScope();
                }
            });

            context.SetValue(Identifier, f);

            return(Completion.Normal);
        }
        public async Task <IHtmlContent> ProcessContentAsync(TagHelperOutput output, CacheContext cacheContext)
        {
            IHtmlContent content = null;

            while (content == null)
            {
                Task <IHtmlContent> result;

                // Is there any request already processing the value?
                if (!_dynamicCacheTagHelperService.Workers.TryGetValue(CacheId, out result))
                {
                    // There is a small race condition here between TryGetValue and TryAdd that might cause the
                    // content to be computed more than once. We don't care about this race as the probability of
                    // happening is very small and the impact is not critical.
                    var tcs = new TaskCompletionSource <IHtmlContent>();

                    _dynamicCacheTagHelperService.Workers.TryAdd(CacheId, tcs.Task);

                    try
                    {
                        var value = await _dynamicCacheService.GetCachedValueAsync(cacheContext);

                        if (value == null)
                        {
                            // The value is not cached, we need to render the tag helper output
                            var processedContent = await output.GetChildContentAsync();

                            using (var sb = StringBuilderPool.GetInstance())
                            {
                                using (var writer = new StringWriter(sb.Builder))
                                {
                                    // Write the start of a cache debug block.
                                    if (_cacheOptions.DebugMode)
                                    {
                                        // No need to optimize this code as it will be used for debugging purpose.
                                        writer.WriteLine();
                                        writer.WriteLine($"<!-- CACHE BLOCK: {cacheContext.CacheId} ({Guid.NewGuid()})");
                                        writer.WriteLine($"         VARY BY: {String.Join(", ", cacheContext.Contexts)}");
                                        writer.WriteLine($"    DEPENDENCIES: {String.Join(", ", cacheContext.Tags)}");
                                        writer.WriteLine($"      EXPIRES ON: {cacheContext.ExpiresOn}");
                                        writer.WriteLine($"   EXPIRES AFTER: {cacheContext.ExpiresAfter}");
                                        writer.WriteLine($" EXPIRES SLIDING: {cacheContext.ExpiresSliding}");
                                        writer.WriteLine("-->");
                                    }

                                    // Always write the content regardless of debug mode.
                                    processedContent.WriteTo(writer, HtmlEncoder);

                                    // Write the end of a cache debug block.
                                    if (_cacheOptions.DebugMode)
                                    {
                                        writer.WriteLine();
                                        writer.WriteLine($"<!-- END CACHE BLOCK: {cacheContext.CacheId} -->");
                                    }

                                    await writer.FlushAsync();
                                }

                                var html = sb.Builder.ToString();

                                var formattingContext = new DistributedCacheTagHelperFormattingContext
                                {
                                    Html = new HtmlString(html)
                                };

                                await _dynamicCacheService.SetCachedValueAsync(cacheContext, html);

                                content = formattingContext.Html;
                            }
                        }
                        else
                        {
                            content = new HtmlString(value);
                        }
                    }
                    catch
                    {
                        content = null;
                        throw;
                    }
                    finally
                    {
                        // Remove the worker task before setting the result.
                        // If the result is null, other threads would potentially
                        // acquire it otherwise.
                        _dynamicCacheTagHelperService.Workers.TryRemove(CacheId, out result);

                        // Notify all other awaiters to render the content
                        tcs.TrySetResult(content);
                    }
                }
                else
                {
                    content = await result;
                }
            }

            return(content);
        }
 public ViewBufferTextWriterContent(bool releaseOnWrite = true)
 {
     _pooledBuilder  = StringBuilderPool.GetInstance();
     _builder        = _pooledBuilder.Builder;
     _releaseOnWrite = releaseOnWrite;
 }