private async Task CreateRoomPageAsync(IServiceProvider serviceProvider, SeederContext context, NodeId roomsPageId, string imageFolder, string englishName, string dutchName, int nightlyRate, int sortIndex)
        {
            var content = EmbeddedContent.New(ContentTypeDefinition.Lookup <RoomDetail>());
            var images  = Directory.GetFiles(Path.Combine(Directory.GetCurrentDirectory(), $"../seed-assets/rooms/{imageFolder}".ToSafeFilePath()));

            var mainImageId = await CreateImageAsync(serviceProvider, context, images.First(), $"{englishName} Image 1");

            this.AddContentValue(content, nameof(RoomDetail.MainImage), NodeReference.New(mainImageId));

            for (var i = 1; i < images.Length; i++)
            {
                var additionalImageId = await CreateImageAsync(serviceProvider, context, images[i], $"{englishName} Image {i + 1}");

                this.AddContentValue(content, nameof(RoomDetail.AdditionalImages), NodeReference.New(additionalImageId));
            }

            this.AddContentValue(content, nameof(RoomDetail.NightlyRate), nightlyRate);
            this.AddContentValue(content, nameof(RoomDetail.DiscountedFrom), new Random().Next(nightlyRate, Convert.ToInt32(nightlyRate * 1.2)));
            this.AddContentValue(content, nameof(RoomDetail.ListDescription), Lorem.Sentence(8, 14), Lorem.Sentence(8, 14));
            this.AddContentValue(content, nameof(RoomDetail.LongDescription), "<p>" + string.Join("</p><p>", Lorem.Paragraphs(6, 16, 5, 10, 3)) + "</p>", "<p>" + string.Join("</p><p>", Lorem.Paragraphs(6, 16, 5, 10, 3)) + "</p>");

            var roomPage = await this.CreatePageAsync(serviceProvider, context, roomsPageId, content, englishName, dutchName, sortIndex);

            context.Rooms.Add(roomPage);
        }
        private async Task CreateBlogPagesAsync(IServiceProvider serviceProvider, SeederContext context, NodeId parentId)
        {
            // Create Blog overview
            var blogContent = EmbeddedContent.New(ContentTypeDefinition.Lookup <SimplePage>());

            this.AddContentValue(blogContent, nameof(ContentPage.NavigationTitle), "Blog", "Blog");

            context.BlogParentId = await this.CreatePageAsync(serviceProvider, context, parentId, blogContent, "Blog", "Blog", 4, "BlogOverview");

            var articleDate = DateTime.Today.AddDays(-_rnd.Next(0, 7));
            var imageFiles  = Directory.GetFiles(Path.Combine(Directory.GetCurrentDirectory(), $"../seed-assets/blog".ToSafeFilePath()));
            var sortIndex   = 0;

            foreach (var imageFile in imageFiles)
            {
                var imageId = await CreateImageAsync(serviceProvider, context, imageFile, $"Blog Article Image {articleDate.ToShortDateString()}");

                var categories = Path.GetFileNameWithoutExtension(imageFile).Split('-').Skip(1);

                var content = EmbeddedContent.New(ContentTypeDefinition.Lookup <BlogArticle>());
                this.AddContentValue(content, nameof(BlogArticle.Image), NodeReference.New(imageId));
                this.AddContentValues(content, nameof(BlogArticle.Categories), categories);
                this.AddContentValue(content, nameof(BlogArticle.PublicationDate), articleDate);
                this.AddContentValue(content, nameof(BlogArticle.Author), Lorem.Words(2, 3));
                this.AddContentValue(content, nameof(BlogArticle.ListDescription), Lorem.Sentence(8, 14), Lorem.Sentence(8, 14));
                this.AddContentValue(content, nameof(BlogArticle.Body), "<p>" + string.Join("</p><p>", Lorem.Paragraphs(6, 16, 5, 10, 3)) + "</p>", "<p>" + string.Join("</p><p>", Lorem.Paragraphs(6, 16, 5, 10, 3)) + "</p>");

                await this.CreatePageAsync(serviceProvider, context, context.BlogParentId, content, Lorem.Words(4, 8), Lorem.Words(4, 8), sortIndex ++);

                articleDate = articleDate.AddDays(-_rnd.Next(0, 7));
            }
        }
        private async Task <EmbeddedContent> CreateOffersModuleAsync(IServiceProvider serviceProvider, SeederContext context)
        {
            var content = EmbeddedContent.New(ContentTypeDefinition.Lookup <OffersMosaic>());

            foreach (var imageFile in Directory.GetFiles(Path.Combine(Directory.GetCurrentDirectory(), $"../seed-assets/offers".ToSafeFilePath())))
            {
                var imageId = await CreateImageAsync(serviceProvider, context, imageFile, "Offer");

                var offer = EmbeddedContent.New(ContentTypeDefinition.Lookup <OfferItem>());

                this.AddContentValue(offer, nameof(OfferItem.Image), NodeReference.New(imageId));
                this.AddContentValue(offer, nameof(OfferItem.Title), Lorem.Words(3, 6), Lorem.Words(3, 6));
                this.AddContentValue(offer, nameof(OfferItem.Text), Lorem.Paragraph(5, 8, 2, 4), Lorem.Paragraph(5, 8, 2, 4));

                this.AddContentValue(content, nameof(OffersMosaic.Offers), offer);
            }

            return(content);
        }
        private async Task CreateFacilityPageAsync(IServiceProvider serviceProvider, SeederContext context, NodeId facilitiesParentId, string imageFolder, string englishName, string dutchName, int sortOrder)
        {
            var content = EmbeddedContent.New(ContentTypeDefinition.Lookup <FacilityPage>());
            var images  = Directory.GetFiles(Path.Combine(Directory.GetCurrentDirectory(), $"../seed-assets/facilities/{imageFolder}".ToSafeFilePath()));

            var imageAssets = new List <string>();

            for (var i = 0; i < images.Length; i++)
            {
                var imageId = await CreateImageAsync(serviceProvider, context, images[i], $"{englishName} Image {i + 1}");

                this.AddContentValue(content, nameof(FacilityPage.Images), NodeReference.New(imageId));
                imageAssets.Add(imageId);
            }

            this.AddContentValue(content, nameof(FacilityPage.ListDescription), Lorem.Sentence(8, 14), Lorem.Sentence(8, 14));

            var facilityPageId = await this.CreatePageAsync(serviceProvider, context, facilitiesParentId, content, englishName, dutchName, sortOrder);

            context.Facilities.Add(facilityPageId);
        }
        private async Task AddHomepageContentAsync(IServiceProvider serviceProvider, SeederContext context, NodeId homepageId)
        {
            var commandBus     = serviceProvider.GetRequiredService <ICommandBus>();
            var contentService = serviceProvider.GetRequiredService <IContentService>();

            var contentType = ContentTypeDefinition.Lookup <Homepage>();
            var content     = EmbeddedContent.New(contentType);

            this.AddContentValue(content, nameof(Homepage.PageTitle), "Welcome", "Welkom");
            this.AddContentValue(content, nameof(Homepage.NavigationTitle), "Home", "Home");

            // Header slider items
            var sliderContentType = ContentTypeDefinition.Lookup <SliderItem>();

            var sliderContent1 = EmbeddedContent.New(sliderContentType);
            var sliderImageId  = await CreateImageAsync(serviceProvider, context, Path.Combine(Directory.GetCurrentDirectory(), @"../seed-assets/hotel/slider-item-1.jpg".ToSafeFilePath()), "Slider Image 1");

            this.AddContentValue(sliderContent1, nameof(SliderItem.BackgroundImage), NodeReference.New(sliderImageId));
            this.AddContentValue(sliderContent1, nameof(SliderItem.Caption), "Welcome to The Redakt Hotel and Resort", "Welkom bij het Redakt Hotel en Resort");
            this.AddContentValue(sliderContent1, nameof(SliderItem.Title), "Experience the Luxury", "Ervaar de Luxe");
            this.AddContentValue(sliderContent1, nameof(SliderItem.Subtitle), "in our Hotel", "in ons Hotel");
            this.AddContentValue(content, nameof(Homepage.SliderItems), sliderContent1);

            var sliderContent2 = EmbeddedContent.New(sliderContentType);

            this.AddContentValue(sliderContent2, nameof(SliderItem.BackgroundImage), NodeReference.New(sliderImageId));
            this.AddContentValue(sliderContent2, nameof(SliderItem.Caption), "Welcome to The Redakt Hotel and Resort", "Welkom bij het Redakt Hotel en Resort");
            this.AddContentValue(sliderContent2, nameof(SliderItem.Title), "Experience Exceptional Dining", "Ervaar Uitzonderlijk Dineren");
            this.AddContentValue(sliderContent2, nameof(SliderItem.Subtitle), "in our Restaurants", "in onze Restaurants");
            this.AddContentValue(content, nameof(Homepage.SliderItems), sliderContent2);

            var sliderContent3 = EmbeddedContent.New(sliderContentType);

            this.AddContentValue(sliderContent3, nameof(SliderItem.BackgroundImage), NodeReference.New(sliderImageId));
            this.AddContentValue(sliderContent3, nameof(SliderItem.Caption), "Welcome to The Redakt Hotel and Resort", "Welkom bij het Redakt Hotel en Resort");
            this.AddContentValue(sliderContent3, nameof(SliderItem.Title), "Experience Ultimate Relaxation", "Ervaar Ultieme Ontspanning");
            this.AddContentValue(sliderContent3, nameof(SliderItem.Subtitle), "in our Spa & Wellness", "in onze Spa & Wellness");
            this.AddContentValue(content, nameof(Homepage.SliderItems), sliderContent3);

            // Room carousel
            this.AddContentValue(content, nameof(Homepage.Modules), this.CreateRoomCarouselModule(serviceProvider, context));

            // Text content
            var textContent = EmbeddedContent.New(ContentTypeDefinition.Lookup <TextWithImage>());
            var imageId     = await CreateImageAsync(serviceProvider, context, Path.Combine(Directory.GetCurrentDirectory(), @"../seed-assets/home/home-text-image.jpg".ToSafeFilePath()), "Homepage Image");

            this.AddContentValue(textContent, nameof(TextWithImage.Image), NodeReference.New(imageId));
            this.AddContentValue(textContent, nameof(TextWithImage.HeadingCaption), "Welcome to The Redakt", "Welkom bij The Redakt");
            this.AddContentValue(textContent, nameof(TextWithImage.Heading), "Demonstration website", "Demonstratie website");
            this.AddContentValue(textContent, nameof(TextWithImage.BodyText), "The Redakt Hotel & Resort is a demo website for the <a href=\"https://www.redaktcms.com\" target=\"_blank\">Redakt Content Management System</a>. Therefore most content is fictional and automatically generated. You can visit the back office application at <a href=\"/redakt\">/redakt</a>. In the back office and application code you can play with many of the features that are part of the Redakt system. Please note, as this website is meant as a showcase for Redakt CMS only, and it does not necessarily reflect best web software development practices. Parts of the website may be functionally incomplete or missing.", "The Redakt Hotel & Resort is een demo website voor het <a href=\"https://www.redaktcms.com\" target=\"_blank\">Redakt Content Management System</a>. Om deze reden is de meeste content fictioneel en automatisch gegenereerd. Je kan de back office applicatie bezoeken op <a href=\"/redakt\">/redakt</a>. In the back office en applicatie code kan je veel van de functionaliteiten uitproberen die onderdeel maken van het Redakt systeem. Let wel, aangezien deze website alleen bedoeld is als showcase voor Redakt CMS, is het niet per se een goed voorbeeld van web software ontwikkeling. Sommige onderdelen van de website kunnen functioneel incompleet zijn.");
            this.AddContentValue(content, nameof(Homepage.Modules), textContent);

            // Facilities grid
            var facilitiesContent = this.CreateFacilitiesModule(serviceProvider, context);

            this.AddContentValue(facilitiesContent, nameof(FacilitiesGrid.HeadingCaption), "Our Facilities", "Onze Faciliteiten");
            this.AddContentValue(facilitiesContent, nameof(FacilitiesGrid.Heading), "Explore The Redakt", "Ontdek The Redakt");
            this.AddContentValue(facilitiesContent, nameof(FacilitiesGrid.IntroText), Lorem.Paragraph(5, 10, 4, 8), Lorem.Paragraph(5, 10, 4, 8));
            this.AddContentValue(content, nameof(Homepage.Modules), facilitiesContent);

            // Offers mosaic
            var offersContent = await this.CreateOffersModuleAsync(serviceProvider, context);

            this.AddContentValue(offersContent, nameof(OffersMosaic.HeadingCaption), "Our Offers", "Onze Aanbiedingen");
            this.AddContentValue(offersContent, nameof(OffersMosaic.Heading), "The Redakt Special Offers", "The Redakt Speciale Aanbiedingen");
            this.AddContentValue(offersContent, nameof(OffersMosaic.IntroText), Lorem.Paragraph(5, 10, 4, 8), Lorem.Paragraph(5, 10, 4, 8));
            this.AddContentValue(content, nameof(Homepage.Modules), offersContent);

            // Latest Blog Articles
            var blogContent = EmbeddedContent.New(ContentTypeDefinition.Lookup <LatestBlogArticles>());

            this.AddContentValue(blogContent, nameof(LatestBlogArticles.Parent), new Link {
                PageId = context.BlogParentId
            });
            this.AddContentValue(blogContent, nameof(LatestBlogArticles.HeadingCaption), "The Redakt Blog", "Het Blog");
            this.AddContentValue(blogContent, nameof(LatestBlogArticles.Heading), "Latest News", "Laatste Nieuw");
            this.AddContentValue(blogContent, nameof(LatestBlogArticles.IntroText), Lorem.Paragraph(5, 10, 4, 8), Lorem.Paragraph(5, 10, 4, 8));
            this.AddContentValue(content, nameof(Homepage.Modules), blogContent);

            var versionId = NodeVersionId.New;
            var contentId = await contentService.CreateContentAsync(contentType, content).NoSync();

            await commandBus.PublishAsync(new Redakt.ContentManagement.Nodes.Commands.AddNodeVersion(homepageId, versionId, contentId, "Version 1", NodeVersionStateKey.New));

            await commandBus.PublishAsync(new Redakt.ContentManagement.Nodes.Commands.PublishNode(homepageId, _englishCulture, versionId, null));

            await commandBus.PublishAsync(new Redakt.ContentManagement.Nodes.Commands.PublishNode(homepageId, _dutchCulture, versionId, null));
        }