示例#1
0
 public override void OnPreInit(ITemplatePage template)
 {
     if (!string.IsNullOrEmpty(masterPageFile))
     {
         template.Page.MasterPageFile = masterPageFile;
     }
 }
示例#2
0
        /// <summary>
        /// Includes the template with the specified key
        /// </summary>
        /// <param name="key">Key used to resolve a template</param>
        /// <param name="model">Template model</param>
        public async Task IncludeAsync(string key, object model = null)
        {
            if (string.IsNullOrEmpty(key))
            {
                throw new ArgumentNullException(nameof(key));
            }

            if (this.PageLookup == null)
            {
                throw new RazorLightException("Can't locate a page as PageLookup is not set");
            }

            PageLookupResult pageResult = PageLookup.GetPage(key);

            if (pageResult.Success)
            {
                ITemplatePage page = pageResult.ViewEntry.PageFactory();
                page.PageContext = new PageContext(this.PageContext.ViewBag)
                {
                    Writer = this.PageContext.Writer
                };

                if (model != null)
                {
                    var modelTypeInfo = new ModelTypeInfo(model.GetType());
                    page.PageContext.ModelTypeInfo = modelTypeInfo;

                    object pageModel = modelTypeInfo.CreateTemplateModel(model);
                    page.SetModel(pageModel);
                }

                await page.ExecuteAsync();
            }
        }
示例#3
0
        public async Task <string> RenderTemplateAsync <T>(ITemplatePage templatePage, T model, IPageContext context)
        {
            TkDebug.AssertArgumentNull(templatePage, nameof(templatePage), this);
            TkDebug.AssertArgumentNull(context, nameof(context), this);

            templatePage.SetModel(model);
            context.Convert <PageContext>().Model = model;
            using (var writer = new StringWriter())
                using (var scope = new MemoryPoolViewBufferScope())
                {
                    var oldWriter = context.Writer;
                    try
                    {
                        context.Writer = writer;
                        var renderer = new TemplateRenderer(this, HtmlEncoder.Default, scope);
                        await renderer.RenderAsync(templatePage).ConfigureAwait(false);

                        return(writer.ToString());
                    }
                    finally
                    {
                        context.Writer = oldWriter;
                    }
                }
        }
示例#4
0
        /// <summary>
        /// Search and compile a template with a given key
        /// </summary>
        /// <param name="key">Unique key of the template</param>
        /// <param name="compileIfNotCached">If true - it will try to get a template with a specified key and compile it</param>
        /// <returns>An instance of a template</returns>
        public async Task <ITemplatePage> CompileTemplateAsync(string key)
        {
            if (IsCachingEnabled)
            {
                var cacheLookupResult = Cache.RetrieveTemplate(key);
                if (cacheLookupResult.Success)
                {
                    return(cacheLookupResult.Template.TemplatePageFactory());
                }
            }

            CompiledTemplateDescriptor templateDescriptor = await Compiler.CompileAsync(key);

            Func <ITemplatePage> templateFactory = FactoryProvider.CreateFactory(templateDescriptor);

            if (IsCachingEnabled)
            {
                Cache.CacheTemplate(
                    key,
                    templateFactory,
                    templateDescriptor.ExpirationToken);
            }

            ITemplatePage templatePage = templateFactory();

            templatePage.DisableEncoding = Options.DisableEncoding;
            return(templatePage);
        }
示例#5
0
        /// <summary>
        /// Parses a template with a given <paramref name="key" />
        /// </summary>
        /// <param name="key">Key used to resolve a template</param>
        /// <param name="model">Template model</param>
        /// <param name="modelType">Type of the model</param>
        /// <param name="viewBag">Dynamic ViewBag (can be null)</param>
        /// <returns>Returns parsed string</returns>
        /// <remarks>Result is stored in cache</remarks>
        public string Parse(string key, object model, Type modelType, ExpandoObject viewBag)
        {
            PageLookupResult result = pageLookup.GetPage(key);

            if (!result.Success)
            {
                throw new RazorLightException($"Can't find a view with a specified key ({key})");
            }

            var pageContext = new PageContext(viewBag)
            {
                ModelTypeInfo = new ModelTypeInfo(modelType)
            };

            foreach (var viewStartPage in result.ViewStartEntries)
            {
                pageContext.ViewStartPages.Add(viewStartPage.PageFactory());
            }

            ITemplatePage page = result.ViewEntry.PageFactory();

            page.PageContext = pageContext;

            return(RunTemplate(page, model));
        }
示例#6
0
        public TemplateRenderer(
            ITemplatePage razorPage,
            IRazorLightEngine razorEngine,
            HtmlEncoder htmlEncoder)
        {
            if (razorPage == null)
            {
                throw new ArgumentNullException(nameof(razorPage));
            }

            if (razorEngine == null)
            {
                throw new ArgumentNullException(nameof(razorEngine));
            }

            if (razorPage == null)
            {
                throw new ArgumentNullException(nameof(razorPage));
            }

            _engine      = razorEngine;
            _htmlEncoder = htmlEncoder;

            RazorPage = razorPage;
        }
示例#7
0
        private void SetModelContext <T>(
            ITemplatePage templatePage,
            TextWriter textWriter,
            T model,
            ExpandoObject viewBag)
        {
            if (textWriter == null)
            {
                throw new ArgumentNullException(nameof(textWriter));
            }

            var pageContext = new PageContext(viewBag)
            {
                ExecutingPageKey = templatePage.Key,
                Writer           = textWriter
            };

            if (model != null)
            {
                pageContext.ModelTypeInfo = new ModelTypeInfo(model.GetType());

                object pageModel = pageContext.ModelTypeInfo.CreateTemplateModel(model);
                templatePage.SetModel(pageModel);

                pageContext.Model = pageModel;
            }

            templatePage.PageContext = pageContext;
        }
示例#8
0
        public void Inject(ITemplatePage page)
        {
            if (page == null)
            {
                throw new ArgumentNullException(nameof(page));
            }

            PropertyInfo[] properties = page.GetType().GetRuntimeProperties()
                                        .Where(p =>
            {
                return
                (p.IsDefined(typeof(RazorInjectAttribute)) &&
                 p.GetIndexParameters().Length == 0 &&
                 !p.SetMethod.IsStatic);
            }).ToArray();

            foreach (var property in properties)
            {
                Type   memberType = property.PropertyType;
                object instance   = services.GetRequiredService(memberType);

                FastPropertySetter setter = _propertyCache.GetOrAdd(property, new FastPropertySetter(property));
                setter.SetValue(page, instance);
            }
        }
示例#9
0
        /// <summary>
        /// Renders a template to the specified <paramref name="textWriter"/>
        /// </summary>
        /// <param name="templatePage">Instance of a template</param>
        /// <param name="model">Template model</param>
        /// <param name="modelType">Type of the model</param>
        /// <param name="viewBag">Dynamic viewBag of the page</param>
        /// <param name="textWriter">Output</param>
        public async Task RenderTemplateAsync(
            ITemplatePage templatePage,
            object model, Type modelType,
            TextWriter textWriter,
            ExpandoObject viewBag = null)
        {
            if (textWriter == null)
            {
                throw new ArgumentNullException(nameof(textWriter));
            }

            var pageContext = new PageContext(viewBag)
            {
                ExecutingPageKey = templatePage.Key,
                Writer           = textWriter
            };

            if (model != null)
            {
                pageContext.ModelTypeInfo = new ModelTypeInfo(modelType);

                object pageModel = pageContext.ModelTypeInfo.CreateTemplateModel(model);
                templatePage.SetModel(pageModel);
            }

            templatePage.PageContext = pageContext;

            using (var renderer = new TemplateRenderer(templatePage, this, HtmlEncoder.Default))
            {
                await renderer.RenderAsync().ConfigureAwait(false);
            }
        }
示例#10
0
        public async Task Ensure_Registered_Properties_Are_Injected()
        {
            var    collection    = new ServiceCollection();
            string expectedValue = "TestValue";
            string templateKey   = "key";

            collection.AddSingleton(new TestViewModel()
            {
                Title = expectedValue
            });
            var propertyInjector = new PropertyInjector(collection.BuildServiceProvider());

            var builder = new StringBuilder();

            builder.AppendLine("@model object");
            builder.AppendLine("@inject RazorLight.Tests.Models.TestViewModel test");
            builder.AppendLine("Hello @test");

            var engine = new EngineFactory().ForEmbeddedResources(typeof(Root));

            engine.Options.DynamicTemplates.Add(templateKey, builder.ToString());
            ITemplatePage templatePage = await engine.CompileTemplateAsync(templateKey);

            //Act
            propertyInjector.Inject(templatePage);

            //Assert
            var prop = templatePage.GetType().GetProperty("test").GetValue(templatePage);

            Assert.NotNull(prop);
            Assert.IsAssignableFrom <TestViewModel>(prop);
            Assert.Equal((prop as TestViewModel).Title, expectedValue);
        }
示例#11
0
        public async Task <ITemplatePage> CompileTemplateAsync(string key)
        {
            TemplateCacheItem item = CacheManager.GetItem("TemplatePage", key,
                                                          Compiler, FactoryProvider).Convert <TemplateCacheItem>();
            Func <ITemplatePage> templateFactory = item.TemplatePageFactory;

            ITemplatePage templatePage = templateFactory();

            templatePage.DisableEncoding = Options.DisableEncoding;
            return(templatePage);
            //if (IsCachingEnabled)
            //{
            //    var cacheLookupResult = Cache.RetrieveTemplate(key);
            //    if (cacheLookupResult.Success)
            //    {
            //        return cacheLookupResult.Template.TemplatePageFactory();
            //    }
            //}

            //CompiledTemplateDescriptor templateDescriptor = await Compiler.CompileAsync(key);
            //Func<ITemplatePage> templateFactory = FactoryProvider.CreateFactory(templateDescriptor);

            //if (IsCachingEnabled)
            //{
            //    Cache.CacheTemplate(
            //        key,
            //        templateFactory,
            //        templateDescriptor.ExpirationToken);
            //}

            //return templateFactory();
        }
示例#12
0
        ///// <summary>
        ///// Gets the sequence of _ViewStart <see cref="ITemplatePage"/> instances that are executed by this view.
        ///// </summary>
        //public IReadOnlyList<ITemplatePage> ViewStartPages { get; }

        /// <inheritdoc />
        public virtual async Task RenderAsync(ITemplatePage page)
        {
            var context = page.PageContext;

            var bodyWriter = await RenderPageAsync(page, context, invokeViewStarts : false).ConfigureAwait(false);

            await RenderLayoutAsync(page, context, bodyWriter).ConfigureAwait(false);
        }
示例#13
0
        public async Task <string> CompileRenderAsync <T>(string key, T model, object initData, ExpandoObject viewBag)
        {
            ITemplatePage template = await CompileTemplateAsync(key).ConfigureAwait(false);

            template.RazorEngine = RazorEngine;

            return(await RenderTemplateAsync(template, model, initData, viewBag).ConfigureAwait(false));
        }
示例#14
0
 /// <summary>
 /// Renders a template to the specified <paramref name="textWriter"/>
 /// </summary>
 /// <param name="templatePage">Instance of a template</param>
 /// <param name="model">Template model</param>
 /// <param name="modelType">Type of the model</param>
 /// <param name="viewBag">Dynamic viewBag of the page</param>
 /// <param name="textWriter">Output</param>
 public Task RenderTemplateAsync <T>(
     ITemplatePage templatePage,
     T model,
     TextWriter textWriter,
     ExpandoObject viewBag = null)
 {
     return(_handler.RenderTemplateAsync(templatePage, model, textWriter, viewBag));
 }
示例#15
0
        public async void SavePage(DocumentGenerationResult result, string uri)
        {
            // Ensure the file extension is set
            if (String.IsNullOrEmpty(result.Extension))
            {
                result.Extension = "html";
            }

            // Construct an intermediate object to hold generated data.
            var intermediate = new IntermediateGenerationResult
            {
                Meta     = result,
                Uri      = Path.Combine(uri ?? "", result.Uri ?? "", $"{result.Name}.{result.Extension}"),
                FilePath = Path.Join(DeploymentPath, uri),
            };

            intermediate.FilePath = Path.Join(DeploymentPath, intermediate.Uri);
            intermediate.Uri      = Path.Combine(WebConfig.Root, intermediate.Uri);

            Log.LogInformation($"Saving document: \"{intermediate.Uri}\"");

            // Move the content to the intermediate object
            if (!String.IsNullOrWhiteSpace(result.Template))
            {
                // The document is templated; render with Razor.

                // Copy the model and set DocumentUri if the model descends
                // from our BaseModel.
                object model = result.Model;
                if (model is BaseModel recordModel)
                {
                    model = recordModel with {
                        DocumentUri = intermediate.Uri
                    };
                }

                // Compile the template and render the document.
                ITemplatePage template = await RazorEngine.CompileTemplateAsync(result.Template);

                intermediate.Content = await RazorEngine.RenderTemplateAsync(template, model);
            }
            else
            {
                // Only text is provided.
                intermediate.Content = result.Text;
            }

            // Execute the post-processors
            foreach (var module in GetModuleInstances <RkDocumentProcessorModule>())
            {
                module.PostProcessDocument(uri, ref intermediate);
            }

            // Write the document to disk.
            Directory.CreateDirectory(Path.GetDirectoryName(intermediate.FilePath));
            await File.WriteAllTextAsync(intermediate.FilePath, intermediate.Content);
        }
    }
示例#16
0
        /// <summary>
        /// Renders a template with a given model
        /// </summary>
        /// <param name="templatePage">Instance of a template</param>
        /// <param name="model">Template model</param>
        /// <param name="modelType">Type of the model</param>
        /// <param name="viewBag">Dynamic viewBag of the template</param>
        /// <returns>Rendered string</returns>
        public async Task <string> RenderTemplateAsync <T>(ITemplatePage templatePage, T model, ExpandoObject viewBag = null)
        {
            using (var writer = new StringWriter())
            {
                await RenderTemplateAsync(templatePage, model, writer, viewBag);

                return(writer.ToString());
            }
        }
 public static async Task RenderIncludedTemplateAsync <T>(ITemplatePage parentPage, BasePage <T> includedTemplatePage, T model)
 {
     using (var scope = new MemoryPoolViewBufferScope())
     {
         var renderer = new TemplateRenderer(Handler, HtmlEncoder.Default, scope);
         SetModelContext(includedTemplatePage, parentPage.PageContext.Writer, model, parentPage.PageContext.ViewBag);
         await renderer.RenderAsync(includedTemplatePage).ConfigureAwait(false);
     }
 }
示例#18
0
        public async Task RenderIncludedTemplateAsync <T>(ITemplatePage templatePage, T model,
                                                          TextWriter textWriter, object initData, ExpandoObject viewBag, TemplateRenderer templateRenderer)
        {
            TkDebug.AssertArgumentNull(textWriter, nameof(textWriter), this);

            SetModelContext(templatePage, textWriter, model, initData, viewBag);

            //templateRenderer.RazorPage = templatePage;
            await templateRenderer.RenderAsync(templatePage).ConfigureAwait(false);
        }
示例#19
0
 public override void OnPreInit(ITemplatePage template)
 {
     var page = template.Page;
     ILanguage language = gateway.GetLanguage(template.CurrentItem);
     if (language != null && !string.IsNullOrEmpty(language.LanguageCode))
     {
         page.Culture = language.LanguageCode;
         page.UICulture = language.LanguageCode;
     }
 }
示例#20
0
 public async Task RenderIncludedTemplateAsync <T>(
     ITemplatePage templatePage,
     T model,
     TextWriter textWriter,
     ExpandoObject viewBag,
     TemplateRenderer templateRenderer)
 {
     SetModelContext(templatePage, textWriter, model, viewBag);
     await templateRenderer.RenderAsync(templatePage).ConfigureAwait(false);
 }
示例#21
0
        public PageRenderer(ITemplatePage page, IPageLookup pageLookup)
        {
            this.razorPage  = page;
            this.pageLookup = pageLookup;

            _htmlEncoder       = HtmlEncoder.Default;
            _bufferScope       = new MemoryPoolViewBufferScope();
            ViewStartPages     = new List <ITemplatePage>();
            PreRenderCallbacks = new PreRenderActionList();
        }
示例#22
0
        /// <summary>
        /// Renders a template with a given model
        /// </summary>
        /// <param name="templatePage">Instance of a template</param>
        /// <param name="model">Template model</param>
        /// <param name="modelType">Type of the model</param>
        /// <param name="viewBag">Dynamic viewBag of the template</param>
        /// <returns>Rendered string</returns>
        public async Task <string> RenderTemplateAsync(ITemplatePage templatePage, object model, Type modelType, ExpandoObject viewBag = null)
        {
            using (var writer = new StringWriter())
            {
                await RenderTemplateAsync(templatePage, model, modelType, writer, viewBag);

                string result = writer.ToString();

                return(result);
            }
        }
示例#23
0
 public TemplateRenderer(
     ITemplatePage razorPage,
     IEngineHandler engineHandler,
     HtmlEncoder htmlEncoder,
     IViewBufferScope bufferScope)
 {
     RazorPage      = razorPage ?? throw new ArgumentNullException(nameof(razorPage));
     _engineHandler = engineHandler ?? throw new ArgumentNullException(nameof(engineHandler));
     _bufferScope   = bufferScope ?? throw new ArgumentNullException(nameof(bufferScope));
     _htmlEncoder   = htmlEncoder ?? throw new ArgumentNullException(nameof(htmlEncoder));
 }
示例#24
0
        private async Task <ViewBufferTextWriter> RenderPageAsync(
            ITemplatePage page,
            PageContext context,
            bool invokeViewStarts)
        {
            var writer = context.Writer as ViewBufferTextWriter;

            if (writer == null)
            {
                Debug.Assert(_bufferScope != null);

                // If we get here, this is likely the top-level page (not a partial) - this means
                // that context.Writer is wrapping the output stream. We need to buffer, so create a buffered writer.
                var buffer = new ViewBuffer(_bufferScope, page.Key, ViewBuffer.ViewPageSize);
                writer = new ViewBufferTextWriter(buffer, context.Writer.Encoding, _htmlEncoder, context.Writer);
            }
            else
            {
                // This means we're writing something like a partial, where the output needs to be buffered.
                // Create a new buffer, but without the ability to flush.
                var buffer = new ViewBuffer(_bufferScope, page.Key, ViewBuffer.ViewPageSize);
                writer = new ViewBufferTextWriter(buffer, context.Writer.Encoding);
            }

            // The writer for the body is passed through the PageContext, allowing things like HtmlHelpers
            // and ViewComponents to reference it.
            var oldWriter   = context.Writer;
            var oldFilePath = context.ExecutingPageKey;

            context.Writer           = writer;
            context.ExecutingPageKey = page.Key;

            try
            {
                //Apply engine-global callbacks
                ExecutePageCallbacks(page, _engine.Options.PreRenderCallbacks.ToList());

                if (invokeViewStarts)
                {
                    // Execute view starts using the same context + writer as the page to render.
                    await RenderViewStartsAsync(context).ConfigureAwait(false);
                }

                await RenderPageCoreAsync(page, context).ConfigureAwait(false);

                return(writer);
            }
            finally
            {
                context.Writer           = oldWriter;
                context.ExecutingPageKey = oldFilePath;
            }
        }
示例#25
0
        private async Task <ViewBufferTextWriter> RenderPageAsync(ITemplatePage page,
                                                                  PageContext context, bool invokeViewStarts)
        {
            if (!(context.Writer is ViewBufferTextWriter writer))
            {
                TkDebug.AssertNotNull(fBufferScope, $"nameof(_bufferScope) is null", this);

                // If we get here, this is likely the top-level page (not a partial) - this means
                // that context.Writer is wrapping the output stream. We need to buffer, so create a buffered writer.
                var buffer = new ViewBuffer(fBufferScope, page.Key, ViewBuffer.ViewPageSize);
                writer = new ViewBufferTextWriter(buffer, context.Writer.Encoding, fHtmlEncoder, context.Writer);
            }
示例#26
0
        private async Task <HtmlString> InternalRenderPart(string key, object model)
        {
            ITemplatePage templatePage = await RazorEngine.CompileTemplateAsync(key);

            templatePage.RazorEngine = RazorEngine;
            templatePage.PageContext = PageContext;
            var objModel = PageContext.ModelTypeInfo.CreateTemplateModel(model ?? PageContext.Model);

            var result = await RazorEngine.Handler.RenderTemplateAsync(templatePage, objModel, PageContext);

            return(new HtmlString(result));
        }
示例#27
0
        private ITemplatePage GetLayoutPage(string layoutKey)
        {
            PageLookupResult layoutPageResult = pageLookup.GetPage(layoutKey);

            if (!layoutPageResult.Success)
            {
                throw new RazorLightException($"Layout cannot be located ({layoutKey})");
            }

            ITemplatePage layoutPage = layoutPageResult.ViewEntry.PageFactory();

            return(layoutPage);
        }
示例#28
0
        public async Task RenderTemplateAsync <T>(ITemplatePage templatePage, T model,
                                                  TextWriter textWriter, object initData, ExpandoObject viewBag)
        {
            TkDebug.AssertArgumentNull(textWriter, nameof(textWriter), this);

            SetModelContext(templatePage, textWriter, model, initData, viewBag);

            using (var scope = new MemoryPoolViewBufferScope())
            {
                var renderer = new TemplateRenderer(this, HtmlEncoder.Default, scope);
                await renderer.RenderAsync(templatePage).ConfigureAwait(false);
            }
        }
示例#29
0
 public override void OnPreInit(ITemplatePage template)
 {
     var item = template.CurrentItem;
     if (item != null)
     {
         template.Page.Init += delegate
         {
             template.Page.Title = item[HeadTitle] as string ?? item.Title;
             AddMeta(template.Page, "keywords", item[MetaKeywords] as string);
             AddMeta(template.Page, "description", item[MetaDescription] as string);
         };
     }
 }
示例#30
0
        public async Task RenderIncludedTemplateAsync(
            ITemplatePage templatePage,
            object model,
            Type modelType,
            TextWriter textWriter,
            ExpandoObject viewBag,
            TemplateRenderer templateRenderer)
        {
            SetModelContext(templatePage, textWriter, model, modelType, viewBag);

            templateRenderer.RazorPage = templatePage;
            await templateRenderer.RenderAsync().ConfigureAwait(false);
        }
示例#31
0
        private async Task RenderPageCoreAsync(ITemplatePage page, PageContext context)
        {
            page.PageContext = context;
            page.IncludeFunc = async(key, model) =>
            {
                ITemplatePage template = await _engine.CompileTemplateAsync(key);

                await _engine.RenderTemplateAsync(template, model, model?.GetType(), context.Writer, context.ViewBag);
            };

            //_pageActivator.Activate(page, context);

            await page.ExecuteAsync().ConfigureAwait(false);
        }
示例#32
0
        /// <summary>
        /// Renders a template to the specified <paramref name="textWriter"/>
        /// </summary>
        /// <param name="templatePage">Instance of a template</param>
        /// <param name="model">Template model</param>
        /// <param name="modelType">Type of the model</param>
        /// <param name="viewBag">Dynamic viewBag of the page</param>
        /// <param name="textWriter">Output</param>
        public async Task RenderTemplateAsync <T>(
            ITemplatePage templatePage,
            T model,
            TextWriter textWriter,
            ExpandoObject viewBag = null)
        {
            SetModelContext(templatePage, textWriter, model, viewBag);

            using (var scope = new MemoryPoolViewBufferScope())
            {
                var renderer = new TemplateRenderer(templatePage, this, HtmlEncoder.Default, scope);
                await renderer.RenderAsync().ConfigureAwait(false);
            }
        }
示例#33
0
 private void ExecutePageCallbacks(ITemplatePage page, IList <Action <ITemplatePage> > callbacks)
 {
     if (callbacks?.Count > 0)
     {
         foreach (var callback in callbacks)
         {
             try
             {
                 callback(page);
             }
             catch (Exception)
             {
                 //Ignore
             }
         }
     }
 }
示例#34
0
        public override void OnPreInit(ITemplatePage template)
        {
            var item = template.CurrentItem;
            if (item == null)
                return;

            var startPage = Find.Closest<StartPage>(item);
            if (startPage == null)
                return;

            string theme = startPage.Theme;

            var exists = template.Page.Cache["ThemeModifier." + theme];
            if (exists == null)
            {
                exists = Directory.Exists(HostingEnvironment.MapPath("~/App_Themes/" + theme));
                template.Page.Cache["ThemeModifier." + theme] = exists;
            }

            if ((bool)exists)
            {
                template.Page.Theme = theme;
            }
        }
示例#35
0
 /// <summary>Applies the concern to the given template.</summary>
 /// <param name="template">The template to apply the concern to.</param>
 public abstract void OnPreInit(ITemplatePage template);