Ejemplo n.º 1
0
        public void Ensure_Passed_Configuration_Is_Applided_OnPhysical()
        {
            IEngineConfiguration configuration = EngineConfiguration.Default;

            var engine = EngineFactory.CreatePhysical(viewsRoot, configuration);

            Assert.Same(configuration, engine.Configuration);
        }
        public ViewToStringRenderer()
        {
            var outputDirectory = Path.GetDirectoryName(Assembly.GetExecutingAssembly().CodeBase);
            var viewsPath       = Path.Combine(outputDirectory, @"PdfGenerator\Views");
            var viewsLocation   = new Uri(viewsPath).LocalPath;

            _engine = EngineFactory.CreatePhysical(viewsLocation);
        }
Ejemplo n.º 3
0
        public override string Parse(string template, dynamic model)
        {
            var root   = _hostingEnvironment.WebRootPath;
            var engine = EngineFactory.CreatePhysical(root);
            var result = engine.ParseString(template,
                                            new { ApplicationName = "ASP.NET Core Web Forms", Title = model.Title });

            return(result);
        }
Ejemplo n.º 4
0
        /*
         * public static string CompileRazor(this string input, object model)
         * {
         *  var engine = EngineFactory.CreatePhysical(@"c:\Windows");
         *  string result = engine.ParseString(input, model);
         *  return result;
         * }
         */

        public static string CompileRazor <T>(this string input, T model)
        {
            var    engine = EngineFactory.CreatePhysical(@"c:\Windows");
            string result = engine.ParseString(input, model);

            result = WebUtility.HtmlDecode(result);

            return(result);
        }
Ejemplo n.º 5
0
        private byte[] CreateFilePDF <T>(IReportsGrandGridView <T> groupedList)
        {
            if (!RunSetCommonValuesForExport)
            {
                throw new InvalidOperationException("You forgot run SetCommonValuesForExport() for set common values.");
            }

            var pdfBytesResult = new byte[0];

            #region Set root paths and give names for files.

            var fileNameWkhtmltopdf   = "wkhtmltopdf.exe";
            var fileNamePDFMarkUpView = "PDFMarkUpView.cshtml";

            var contentRootPath = _environment.ContentRootPath;

            var pathContentPDF            = $"{contentRootPath}\\Content\\PDF";
            var pathContentPDFCssStyle    = $"{pathContentPDF}\\Site.css";
            var pathContentPDFWkhtmltopdf = $"{pathContentPDF}\\{fileNameWkhtmltopdf}";

            var pathFileInfo = new FileInfo(pathContentPDFWkhtmltopdf);

            #endregion

            if (File.Exists(pathContentPDFWkhtmltopdf))
            {
                var pdfModel = new ReportsPDFCommonView(pathContentPDFCssStyle, GroupById, GetPeriodPDFCell())
                {
                    PDFGrandModel = CreateReportsGrandGridModel(groupedList)
                };

                #region Parse view.

                var engineRazorLight             = EngineFactory.CreatePhysical(pathContentPDF);
                var htmlFromParsedViewRazorLight = engineRazorLight.Parse(fileNamePDFMarkUpView, pdfModel);

                var settings = new ConversionSettings(
                    pageSize: PageSize.A4,
                    orientation: PageOrientation.Landscape,
                    margins: new WkWrap.Core.PageMargins(5, 10, 5, 10),
                    grayscale: false,
                    lowQuality: false,
                    quiet: false,
                    enableJavaScript: true,
                    javaScriptDelay: null,
                    enableExternalLinks: true,
                    enableImages: true,
                    executionTimeout: null);

                pdfBytesResult = new HtmlToPdfConverter(pathFileInfo).ConvertToPdf(htmlFromParsedViewRazorLight, Encoding.UTF8, settings);

                #endregion
            }

            return(pdfBytesResult);
        }
Ejemplo n.º 6
0
        public ViewRenderService(ITemplateSettings templateSettings)
        {
            if (templateSettings == null)
            {
                throw new ArgumentNullException(nameof(templateSettings));
            }

            // TODO:
            _engine = EngineFactory.CreatePhysical(templateSettings.TemplatesFolderPath);
        }
Ejemplo n.º 7
0
        public void Can_Parse_Physical_Files()
        {
            string root = PathUtility.GetViewsPath();

            var engine = EngineFactory.CreatePhysical(root);

            string result = engine.Parse("Test.cshtml", new TestViewModel());

            Assert.NotNull(result);
        }
Ejemplo n.º 8
0
        public string Generate(string template, object model)
        {
            if (_engine == null)
            {
                _engine = EngineFactory.CreatePhysical(Configuration.GetProjectDirectory());
                Assert.IsNotNull(_engine);

                _engine.Configuration.Namespaces.AddRange(Configuration.GetArray(Constants.Configuration.GenerateCode.Imports));
            }

            return(_engine.ParseString(template, model));
        }
Ejemplo n.º 9
0
        public IActionResult Index()
        {
            const string content = "Hello @Model.Name. Welcome to @Model.Title repository";
            var          engine  = EngineFactory.CreatePhysical(@"c:\Windows" /*it's fake, not needed and going to fix in 2.0.0*/);

            var model = new
            {
                Name  = "Posht-Kohi",
                Title = "RazorLight"
            };

            string result = engine.ParseString(content, model);

            return(Content(result));
        }
        public string Index()
        {
            string templatePath = $@"{Directory.GetCurrentDirectory()}\EmailTemplates";

            IRazorLightEngine engine = EngineFactory.CreatePhysical(templatePath);

            var model = new Notification
            {
                Name    = "Jone",
                Title   = "Test Email",
                Content = "This is a test"
            };

            string result = engine.Parse("template.cshtml", model);

            return(result);
        }
Ejemplo n.º 11
0
        private void Send <T>(string Activity, string Subject, String Name, String Email, String View, T model, List <String> UserCC = null)
        {
            try
            {
                IRazorLightEngine engine = EngineFactory.CreatePhysical(@"" + Path.GetFullPath("Emails"));
                var _config        = _service.GetService <ConfigHelper>();
                var emailForm      = _config.GetConfig("smtp.from.email");
                var password       = _config.GetConfig("smtp.password");
                var SmtpServer     = _config.GetConfig("smtp.server");
                var SmtpPortNumber = _config.GetConfig("smtp.port");
                var useSSL         = _config.GetConfig("smtp.ssl");
                var message        = new MimeMessage();
                var bodyBuilder    = new BodyBuilder();
                message.From.Add(new MailboxAddress("*****@*****.**", emailForm));
                message.To.Add(new MailboxAddress(Name, Email));

                if (UserCC != null)
                {
                    foreach (var row in UserCC)
                    {
                        message.Cc.Add(new MailboxAddress(row, row));
                    }
                }


                message.Subject      = Subject;
                bodyBuilder.HtmlBody = engine.Parse(View + ".cshtml", model);
                message.Body         = bodyBuilder.ToMessageBody();
                using (var client = new SmtpClient())
                {
                    client.Connect(SmtpServer, int.Parse(SmtpPortNumber), Boolean.Parse(useSSL));
                    client.AuthenticationMechanisms.Remove("XOAUTH2");
                    client.Authenticate(emailForm, password);
                    client.Send(message);
                    client.Disconnect(true);
                    Console.WriteLine(Activity + " notification has been sent at " + DateTime.Now);
                }
            }
            catch (Exception e)
            {
                Console.WriteLine(e.ToString());
            }
        }
        public async Task <string> Index1()
        {
            var engine = EngineFactory.CreatePhysical(@"D:\Email");

            var message = _messageRepository.FindByMessageTemplateTypeByID("hlw").Result;

            var user = await GetCurrentUserAsync();

            var model = new
            {
                UserName  = _userStore.GetUserNameAsync(user).Result.ToString(),
                FirstName = _userStore.GetFirstName(user),
                LastName  = _userStore.GetLastName(user),
                Email     = await _userStore.GetEmailAsync(user),
            };

            string result = engine.ParseString(message.Body, model);

            await _emailSender.SendEmailAsync("*****@*****.**", message.Subject, result);

            return(String.Format("Sucess"));
        }
Ejemplo n.º 13
0
        void IWebNoteService.SendEmail(WebNote note, string loggedInEmail, string email)
        {
            var engine = EngineFactory.CreatePhysical(Path.Combine(_hostingEnvironment.ContentRootPath, "Templates", "Email"));
            var model  = new
            {
                Sender  = loggedInEmail,
                Title   = note.Title,
                Color   = note.Color,
                Content = note.Content,
            };
            string result = engine.Parse("basic.cshtml", model);


            var message = new MimeMessage();

            message.From.Add(new MailboxAddress("WebNotes", "*****@*****.**"));
            message.To.Add(new MailboxAddress(email, email));
            message.Subject = "WebNote from " + loggedInEmail;
            message.Body    = new TextPart("html")
            {
                Text = result
            };

            using (var client = new SmtpClient())
            {
                client.Connect("smtp.mailgun.org", 587, false);
                // Note: since we don't have an OAuth2 token, disable // the XOAUTH2 authentication mechanism
                client.AuthenticationMechanisms.Remove("XOAUTH2");
                // Note: only needed if the SMTP server requires authentication
                client.Authenticate(
                    Environment.GetEnvironmentVariable("emailClientUsername"),
                    Environment.GetEnvironmentVariable("emailClientPassword"));
                client.Send(message);
                client.Disconnect(true);
            }
            //
        }
        public async Task <IActionResult> Index(SendEmailViewModel model)
        {
            var engine = EngineFactory.CreatePhysical(@"D:\Email");

            var user = await GetCurrentUserAsync();

            string messageTypeID = model.MessageTypeID.ToString();

            var message = _messageRepository.FindByMessageTemplateTypeByID(messageTypeID).Result;

            var modelitem = new
            {
                UserName  = _userStore.GetUserNameAsync(user).Result.ToString(),
                FirstName = _userStore.GetFirstName(user),
                LastName  = _userStore.GetLastName(user),
                Email     = _userStore.GetEmailAsync(user).Result,
            };

            string result = engine.ParseString(message.Body, modelitem);

            await _emailSender.SendEmailGridAsync(model.Email, message.Subject, result);

            return(Ok());
        }
Ejemplo n.º 15
0
 public IActionResult FooAction()
 {
     var tempatePath          = Path.Combine(_env.ContentRootPath, "Areas/Services/Views/Quotations/SpecificForms/PC/PCReceipts.cshtml");
     IRazorLightEngine engine = EngineFactory.CreatePhysical(templatePath);
Ejemplo n.º 16
0
        public void PhysicalFactory_Throws_On_RootNull()
        {
            var action = new Action(() => EngineFactory.CreatePhysical(null));

            Assert.Throws <ArgumentNullException>(action);
        }
Ejemplo n.º 17
0
        protected virtual string ParseTemplate(string templatePath, string templateName, MailContext context)
        {
            var engine = EngineFactory.CreatePhysical($"{_hostingEnvironment.ContentRootPath}{templatePath}");

            return(engine.Parse(templateName, context));
        }
Ejemplo n.º 18
0
 public static void Main(string[] args)
 {
     var engine = EngineFactory.CreatePhysical(@"D:\MyProjects\RazorLight\sandbox\Sandbox\Views");
     var model  = new TestViewModel();
 }
Ejemplo n.º 19
0
 public RazorEngine(IOptionsSnapshot <AppSettings> settings) : base(settings)
 {
     _templateSettings = JsonConvert.DeserializeObject <TemplateSettings>(File.ReadAllText(Path.Combine(_settings.TemplatePath, "template.json")));
     _engine           = EngineFactory.CreatePhysical(Path.Combine(_settings.TemplatePath));
 }
Ejemplo n.º 20
0
        private string GenerateBodyHtml(string viewName, object model)
        {
            IRazorLightEngine _razor = EngineFactory.CreatePhysical($@"{Directory.GetCurrentDirectory()}\Views\Email");

            return(_razor.Parse($"{viewName}.cshtml", model));
        }
Ejemplo n.º 21
0
        /// <summary>
        /// This method gets called by the runtime. Use this method to add services to the container.
        /// For more information on how to configure your application, visit http://go.microsoft.com/fwlink/?LinkID=398940
        /// </summary>
        /// <param name="services">The services.</param>
        public void ConfigureServices(IServiceCollection services)
        {
            // Add MVC services to the services container.
            // Build the intermediate service provider

            services.AddLocalization(options => options.ResourcesPath = "Resources");

            services.AddAntiforgery(options => options.HeaderName = "X-XSRF-TOKEN");

            services.AddScoped <ValidateMimeMultipartContentFilter>();

            // Add functionality to inject IOptions<T>
            services.AddOptions();

            // Add our Config object so it can be injected
            var appSettingsSection = Configuration.GetSection("AppSettings");

            services.Configure <AppSettings>(appSettingsSection);
            services.Configure <AppSettings>(settings =>
            {
                if (HttpContextAccessor.HttpContext == null)
                {
                    return;
                }
                var request       = HttpContextAccessor.HttpContext.Request;
                settings.Urls.Api = $"{request.Scheme}://{request.Host.ToUriComponent()}";
            });

            appSettingsSection.Bind(AppSettings);

            // *If* you need access to generic IConfiguration this is **required**
            services.AddSingleton(Configuration);

            ConfigAuth(services);

            // Enable Cors
            services.AddCors(options =>
            {
                options.AddPolicy("CorsPolicy",
                                  builder => builder
                                  .AllowAnyOrigin()
                                  .AllowAnyMethod()
                                  .AllowAnyHeader()
                                  .AllowCredentials()
                                  );
            });

            services.AddMvc(options =>
            {
                //http://www.dotnetcurry.com/aspnet/1314/aspnet-core-globalization-localization
                options.Conventions.Add(new HybridModelBinderApplicationModelConvention());
                options.Conventions.Add(new NameSpaceVersionRoutingConvention());
                // Make authentication compulsory across the board (i.e. shut
                // down EVERYTHING unless explicitly opened up).
                var policy = new AuthorizationPolicyBuilder()
                             .RequireAuthenticatedUser()
                             .RequireClaim(ClaimTypes.Name)
                             .RequireClaim(ClaimTypes.NameIdentifier)
                             .Build();

                options.Filters.Add(new AuthorizeFilter(policy));
            }
                            ).AddJsonOptions(opts =>
            {
                // Force Camel Case to JSON
                opts.SerializerSettings.ContractResolver = new CamelCasePropertyNamesContractResolver();
            }
                                             )
            .AddViewLocalization()
            .AddDataAnnotationsLocalization();

            //https://www.billbogaiv.com/posts/hybrid-model-binding-in-aspnet-core-10-rc2
            services.Configure <MvcOptions>(options =>
            {
                /**
                 * This is needed since the provider uses the existing `BodyModelProvider`.
                 * Ref. https://github.com/aspnet/Mvc/blob/1.0.0-rc2/src/Microsoft.AspNetCore.Mvc.Core/ModelBinding/Binders/BodyModelBinder.cs
                 */
                var readerFactory = services.BuildServiceProvider().GetRequiredService <IHttpRequestStreamReaderFactory>();

                options.ModelBinderProviders.Insert(0, new DefaultHybridModelBinderProvider(options.InputFormatters, readerFactory));
                // options.Filters.Add(new CorsAuthorizationFilterFactory("CorsPolicy"));
            });

            services.AddSwaggerGen(c =>
            {
                c.SwaggerDoc("v1", new Info {
                    Title          = AppSettings.Information.Name,
                    Version        = AppSettings.Information.Version,
                    Description    = AppSettings.Information.Description,
                    TermsOfService = AppSettings.Information.TermsOfService,
                    Contact        = new Contact {
                        Name  = AppSettings.Information.ContactName,
                        Email = AppSettings.Information.ContactEmail
                    },
                    License = new License {
                        Name = AppSettings.Information.LicenseName,
                        Url  = AppSettings.Information.LicenseUrl
                    }
                });

                //Set the comments path for the swagger json and ui.
                var basePath = PlatformServices.Default.Application.ApplicationBasePath;
                var xmlPath  = Path.Combine(basePath, "MasterApi.xml");
                c.IncludeXmlComments(xmlPath);
            });

            // Injection
            services.AddTransient <IHttpContextAccessor, HttpContextAccessor>();

            services.Configure <RequestLocalizationOptions>(
                options => {
                var supportedCultures = new List <CultureInfo> {
                    new CultureInfo("en"),
                    new CultureInfo("en-US"),
                    new CultureInfo("pt"),
                    new CultureInfo("pt-BR")
                };
                var defaultCulture            = supportedCultures[1].Name;
                options.DefaultRequestCulture = new RequestCulture(defaultCulture, defaultCulture);
                options.SupportedCultures     = supportedCultures;
                options.SupportedUICultures   = supportedCultures;
            }
                );

            // SignalR
            var authorizer = new HubAuthorizeAttribute(_tokenOptions);
            var module     = new AuthorizeModule(authorizer, authorizer);

            services.AddSignalR(options =>
            {
                options.EnableJSONP = true;
                options.Hubs.EnableJavaScriptProxies = true;
                options.Hubs.EnableDetailedErrors    = true;
                options.Hubs.PipelineModules.Add(module);
            });

            services.AddCustomHeaders();

            var connString = Configuration.GetConnectionString("DbConnection");

            //services.AddDbContext<DualAuthContext>(options =>
            //	options.UseSqlServer(Configuration.GetConnectionString("DefaultConnection")));

            services.AddDbContext <AppDbContext>(options =>
            {
                switch (AppSettings.DbSettings.InMemoryProvider)
                {
                case true:
                    options.UseInMemoryDatabase(connString);
                    break;

                default:
                    options.UseSqlServer(connString, b => b.MigrationsAssembly("MasterApi.Data"));
                    break;
                }
            });

            services.AddHangfire(x => x.UseSqlServerStorage(connString));

            // Repositories
            services.AddScoped(typeof(IDataContextAsync), typeof(AppDbContext));
            services.AddScoped(typeof(IUnitOfWorkAsync), typeof(UnitOfWork));
            services.AddScoped(typeof(IRepositoryAsync <>), typeof(Repository <>));
            services.AddTransient <DataSeeder>();

            //Services
            services.AddScoped(typeof(IService <>), typeof(Service <>));

            services.AddScoped(typeof(IAuthService), typeof(AuthService));
            services.AddScoped(typeof(IUserAccountService), typeof(UserAccountService));
            services.AddScoped(typeof(INotificationService), typeof(NotificationService));
            services.AddScoped(typeof(IGeoService), typeof(GeoService));
            services.AddScoped(typeof(IUserProfileService), typeof(UserProfileService));
            services.AddScoped(typeof(ILookupService), typeof(LookupService));

            //Infrastructure
            services.AddSingleton(typeof(ICrypto), typeof(DefaultCrypto));
            services.AddSingleton(typeof(ISmsSender), typeof(SmsSender));
            services.AddSingleton(typeof(IEmailSender), typeof(EmailSender));

            services.AddSingleton(typeof(IRazorLightEngine), s => EngineFactory.CreatePhysical($"{Directory.GetCurrentDirectory()}\\Views"));

            var asm          = Assembly.GetEntryAssembly();
            var subjectFiles = asm.GetManifestResourceNames().Where(x => x.Contains("subjects.json"));

            var emailSubjects = new Dictionary <string, Dictionary <string, string> >();

            subjectFiles.ForEach(file => {
                var domain   = file.Split('.');
                var subjects = asm.ParseFromJson(file);
                emailSubjects.Add(domain[3], subjects);
            });

            services.AddSingleton(typeof(IEmailSubjects), emailSubjects);

            services.AddSingleton <IHttpContextAccessor, HttpContextAccessor>();

            //Identity
            services.AddScoped(typeof(IUserInfo), s => new UserIdentityInfo(s.GetService <IHttpContextAccessor>().HttpContext.User));
        }
Ejemplo n.º 22
0
        public string Parse <T>(string template, T model, bool isHtml = true)
        {
            var engine = EngineFactory.CreatePhysical("/");

            return(engine.ParseString(template, model));
        }
Ejemplo n.º 23
0
        public async Task <int> SendBookingConfirmEmail(BookingEmailViewModel emailViewModel, string hostEmail, string hostName)
        {
            //var engine = EngineFactory.CreatePhysical(_appSettings.EmailTemplateFolder);
            var engine = EngineFactory.CreatePhysical($"{Directory.GetCurrentDirectory()}\\Content\\EmailTemplates");

            emailViewModel.EmailHeader = $"Hi, thanks for your booking";
            var emailContentForGuests = engine.Parse(_appSettings.BookingGuestsEmailTemplate, emailViewModel);

            emailViewModel.EmailHeader = $"Hi, you have a new booking";
            emailViewModel.IsHost      = true;
            var emailContentForHost = engine.Parse(_appSettings.BookingGuestsEmailTemplate, emailViewModel);

            var emailLogs = new List <EmailLog>();

            var particiants = string.Join(",", emailViewModel.BookingParticipants.Select(x => x.Email));

            if (_appSettings.Environment != "prod")
            {
                particiants = "*****@*****.**";

                emailLogs.Add(new EmailLog
                {
                    ListingId   = emailViewModel.ListingId,
                    FromAddress = _appSettings.DefaultEmailAddress,
                    ToAddress   = string.Join(",", particiants),
                    Subject     = _appSettings.BookingEmailSubject,
                    Content     = emailContentForGuests,
                    CreatedDate = DateTime.Now,
                    //MessageId = x.Result.MessageID,
                    //TransactionId = x.Result.TransactionID,
                    Status = true
                });

                emailLogs.Add(new EmailLog
                {
                    ListingId   = emailViewModel.ListingId,
                    FromAddress = _appSettings.DefaultEmailAddress,
                    ToAddress   = hostEmail,
                    Subject     = _appSettings.BookingEmailSubject,
                    Content     = emailContentForHost,
                    CreatedDate = DateTime.Now,
                    //MessageId = x.Result.MessageID,
                    //TransactionId = x.Result.TransactionID,
                    Status = true
                });
            }
            else
            {
                var sendList = new List <Task>
                {
                    ElasticEmailClient.Send(_appSettings.BookingEmailSubject, _appSettings.DefaultEmailAddress, _appSettings.DefaultEmailName, to: particiants, bodyHtml: emailContentForGuests, isTransactional: true)
                    .ContinueWith(x => emailLogs.Add(new EmailLog
                    {
                        ListingId     = emailViewModel.ListingId,
                        FromAddress   = _appSettings.DefaultEmailAddress,
                        ToAddress     = string.Join(",", particiants),
                        Subject       = _appSettings.BookingEmailSubject,
                        Content       = emailContentForGuests,
                        CreatedDate   = DateTime.Now,
                        MessageId     = x.Result.MessageID,
                        TransactionId = x.Result.TransactionID,
                        Status        = true
                    })),
                    ElasticEmailClient.Send(_appSettings.BookingEmailSubject, _appSettings.DefaultEmailAddress, _appSettings.DefaultEmailName, to: hostEmail, bodyHtml: emailContentForHost, isTransactional: true)
                    .ContinueWith(x => emailLogs.Add(new EmailLog
                    {
                        ListingId     = emailViewModel.ListingId,
                        FromAddress   = _appSettings.DefaultEmailAddress,
                        ToAddress     = hostEmail,
                        Subject       = _appSettings.BookingEmailSubject,
                        Content       = emailContentForHost,
                        CreatedDate   = DateTime.Now,
                        MessageId     = x.Result.MessageID,
                        TransactionId = x.Result.TransactionID,
                        Status        = true
                    }))
                };

                await Task.WhenAll(sendList);
            }

            return(await _emailLogRepository.LogEmail(emailLogs));

            //return sendList.Select(x => x.Result).ToList();
        }
Ejemplo n.º 24
0
        static void Main(string[] args)
        {
            //0 read options from args
            var options = new Options();

            if (args.Length > 0 && args[0] == "--prod")
            {
                options.Environment = Environment.Prod;
            }
            else
            {
                options.Environment = Environment.Dev;
            }

            //1 load configuration from src folder
            var builder = new ConfigurationBuilder()
                          .AddJsonFile(new FileInfo("appsettings.json").FullName, false, true)
                          .AddEnvironmentVariables();
            var configuration = builder.Build();

            var webContentPaths = new WebContentPaths();

            configuration.GetSection("WebContent").Bind(webContentPaths);

            //2 set base directory of template folder
            var fileInfo = new FileInfo(webContentPaths.Global.DefaultRazorTemplateFolderPath);
            var engine   = EngineFactory.CreatePhysical(fileInfo.FullName);

            //3 generate html files, for each culture:
            var mdParserService      = new MdContentParser();
            var staticAssetsResolver = new StaticAssetsPathResolver();

            foreach (Culture culture in webContentPaths.Cultures)
            {
                //3.1 load model for culture

                //3.1.1 load configuration file for this culture
                var mdParserDecorator    = new MdRazorPageDecorator(webContentPaths.Global, culture, mdParserService, staticAssetsResolver, options);
                var confPath             = new FileInfo(culture.ConfigurationFilePath).FullName;
                var cultureConfigBuilder = new ConfigurationBuilder()
                                           .AddJsonFile(confPath, false, true)
                                           .Build();
                var cultureStructure = new WebContentStructure();
                cultureConfigBuilder.GetSection("WebContentStructure").Bind(cultureStructure);

                var pagesModel = new List <IRazorPage>();

                //3.1.2 add home information if available
                if (cultureStructure.Home != null)
                {
                    var homeParser = new HomePage(mdParserDecorator, cultureStructure);
                    pagesModel.Add(homeParser);
                }

                //3.2 loading pages based on culture configuration
                foreach (var model in pagesModel)
                {
                    ((dynamic)model.ExpandoPageData).Base = mdParserDecorator;
                    //3.2.1 generate html string based on template file and model
                    string indexHtml = engine.Parse(model.PageTemplatePath, model, model.ExpandoPageData);

                    //3.2.2 save to output folder
                    string outputFolder = webContentPaths.Global.OutputFolderPath;
                    if (culture.Key != webContentPaths.Global.DefaultCulture)
                    {
                        outputFolder = Path.Combine(outputFolder, culture.Key);
                    }

                    if (!Directory.Exists(outputFolder))
                    {
                        Directory.CreateDirectory(outputFolder);
                    }
                    File.WriteAllText(Path.Combine(outputFolder, model.PageTemplatePath.Replace(".cshtml", ".html")), indexHtml);
                }
            }
        }