### Start a Site in Kentico Xperience 13 Source: https://docs.kentico.com/13/api/configuration/sites Shows how to start a site that is currently stopped. It retrieves the site object and then uses the SiteInfoProvider.RunSite method, passing the site's name. ```csharp // Gets the site SiteInfo site = SiteInfo.Provider.Get("NewSite"); if (site != null) { // Starts the site SiteInfoProvider.RunSite(site.SiteName); } ``` -------------------------------- ### Start an A/B Test in Kentico Xperience 13 Source: https://docs.kentico.com/13/api/on-line-marketing/a-b-testing This C# code snippet illustrates how to start an A/B test in Kentico Xperience 13. It retrieves a specific A/B test, checks its current status, and if it's not running or scheduled for the future, it sets the start and end dates to initiate the test. The test automatically becomes 'Running' once its start time passes. ```csharp // Gets the A/B test created for the "/LandingPage" page ABTestInfo test = ABTestInfo.Provider.Get() .WhereEquals("ABTestOriginalPage", "/LandingPage") .OnSite("MySIte") .TopN(1) .FirstOrDefault(); // Checks that the test exists and is not already running // Starts the test at the current time if it is scheduled to start in the future if ((test?.ABTestOpenFrom == DateTime.MinValue) || (test?.ABTestOpenFrom > DateTime.Now)) { // Configures the test to start at the current time and end in a month test.ABTestOpenFrom = DateTime.Now; test.ABTestOpenTo = DateTime.Now.AddMonths(1); // Saves the test - the test automatically switches to the Running status when the start time is in the past ABTestInfo.Provider.Set(test); } ``` -------------------------------- ### Retrieve Media File URLs with IMediaFileUrlRetriever (C#) Source: https://docs.kentico.com/13/api/content-management/media-libraries This example illustrates how to obtain absolute and relative URLs for media files using the IMediaFileUrlRetriever service. It demonstrates basic retrieval and how to apply parameters like size constraints and content disposition options for customized URLs. Ensure the Kentico.Xperience.AspNet.Mvc5 or Kentico.Xperience.AspNetCore.WebApp NuGet packages are installed. ```csharp /* * The IMediaFileUrlRetriever is a service class that provides URL resolution for media files * in Xperience web applications (projects using the Kentico.Xperience.AspNet.Mvc5 or * Kentico.Xperience.AspNetCore.WebApp NuGet packages). */ // Initializes an instance of a service used for media file URL retrieval IMediaFileUrlRetriever urlRetriever = Service.Resolve(); // Gets an arbitrary media file object MediaFileInfo mediaFile = MediaFileInfo.Provider.Get(42); // Gets an IMediaFileUrl object that contains the absolute and relative URLs to the given media file IMediaFileUrl fileUrl = urlRetriever.Retrieve(mediaFile); // Additionally, you can further parameterize retrieved URLs via extension methods on the IMediaFileUrl object string fileUrlParameterized = urlRetriever.Retrieve(mediaFile) // Scales the retrieved image to be no larger than 400px on either side, // maintaining aspect ratio .WithSizeConstraint(SizeConstraint.MaxWidthOrHeight(400)) // Gets the relative path to the media file .RelativePath; string fileUrlParameterized2 = urlRetriever.Retrieve(mediaFile) // Sets the Content disposition of the URL to 'attachment.' // Accessing the link results in an immediate download of the media file. .WithOptions(new FileUrlOptions { AttachmentContentDisposition = true }) // Gets the relative path to the media file .RelativePath; ``` -------------------------------- ### Start Automation Process for Contact (C#) Source: https://docs.kentico.com/13/api/on-line-marketing/marketing-automation Initiates a marketing automation process for a specific contact. This requires retrieving the contact and the desired automation process, then using the AutomationManager to start the process. Ensure the user context has sufficient permissions. ```csharp // Gets the first contact in the system whose last name is 'Smith' ContactInfo contact = ContactInfo.Provider.Get() .WhereEquals("ContactLastName", "Smith") .TopN(1) .FirstOrDefault(); // Gets the marketing automation process WorkflowInfo process = WorkflowInfoProvider.GetWorkflowInfo("NewProcess", WorkflowTypeEnum.Automation); if ((contact != null) && (process != null)) { /* Creates an automation manager instance. Note: You need to initialize the instance under a specific user. When running the code in the context of the administration application, you can get the current user from 'MembershipContext.AuthenticatedUser'. In other scenarios, such as the code of the live site application or various asynchronous actions, you need to specify a user account with sufficient permissions, for example 'UserInfoProvider.AdministratorUser'. */ AutomationManager manager = AutomationManager.GetInstance(MembershipContext.AuthenticatedUser); // Starts the process for the contact manager.StartProcess(contact, process.WorkflowID); } ``` -------------------------------- ### Sign-in and Sign-out Actions Example (C#) Source: https://docs.kentico.com/13/managing-users/user-registration-and-authentication/setting-up-authentication This C# code demonstrates the implementation of sign-in and sign-out actions within an ASP.NET Core MVC controller. It includes a GET action for displaying the sign-in form and a POST action to handle user authentication using SignInManager and logging potential errors. ```csharp using System; using System.Net; using System.Threading.Tasks; using Microsoft.AspNetCore.Mvc; using Microsoft.AspNetCore.Http; using Microsoft.AspNetCore.Authorization; using Microsoft.AspNetCore.Identity; using CMS.Base; using CMS.Core; using CMS.Membership; using CMS.Base.UploadExtensions; using Kentico.Membership; using LearningKitCore.Models.Users.Account; /// /// Basic action that displays the sign-in form. /// public IActionResult SignIn() { return View(); } /// /// Handles authentication when the sign-in form is submitted. Accepts parameters posted from the sign-in form via the SignInViewModel. /// [HttpPost] [ValidateAntiForgeryToken] public async Task SignIn(SignInViewModel model, string returnUrl) { // Validates the received user credentials based on the view model if (!ModelState.IsValid) { // Displays the sign-in form if the user credentials are invalid return View(); } // Attempts to authenticate the user against the Xperience database var signInResult = Microsoft.AspNetCore.Identity.SignInResult.Failed; try { signInResult = await signInManager.PasswordSignInAsync(model.UserName, model.Password, model.RememberMe, false); } catch (Exception ex) { // Logs an error into the Xperience event log if the authentication fails eventLogService.LogException("MvcApplication", "AUTHENTICATION", ex); } } ``` -------------------------------- ### Update Multiple Products (SKUs) in Kentico Xperience 13 Source: https://docs.kentico.com/13/api/e-commerce/products Provides an example of updating multiple products (SKUs) in Kentico Xperience 13. It retrieves products whose names start with 'New', converts their names to uppercase, and saves the modifications. ```csharp // Gets all products whose name starts with 'New' var products = SKUInfo.Provider.Get() .WhereStartsWith("SKUName", "New") .WhereNull("SKUOptionCategoryID"); // Loops through the products foreach (SKUInfo modifyProduct in products) { // Updates the product properties modifyProduct.SKUName = modifyProduct.SKUName.ToUpperCSafe(); // Saves the changes to the database SKUInfo.Provider.Set(modifyProduct); } ``` -------------------------------- ### Example Target Database Query for Source Field Source: https://docs.kentico.com/13/external-utilities/kentico-xperience-import-toolkit/importing-data-from-external-sources An example of using a query against the target database to retrieve a value for import. ```text # SELECT TOP 1 … ``` -------------------------------- ### Example File Path Reference for Source Field Source: https://docs.kentico.com/13/external-utilities/kentico-xperience-import-toolkit/importing-data-from-external-sources An example of specifying a file path for binary data import, which can be a static path or dynamically generated using a macro expression. ```text # C:\\files\\attachments\\{%AttachmentName%} ``` -------------------------------- ### Setup New Page Search Index Source: https://docs.kentico.com/13/api/configuration/smart-search This C# code configures and sets up a new page search index in Kentico. It defines index properties, settings for allowed content (class names, path, site), assigns cultures, and creates a rebuild task. This process ensures that pages can be effectively indexed and searched. ```csharp // Gets the 'en-US' culture for the index CultureInfo culture = CultureInfo.Provider.Get("en-US"); // Creates a new page search index SearchIndexInfo pageIndex = new SearchIndexInfo() { IndexDisplayName = "Page index", IndexName = "PageIndex", IndexProvider = SearchIndexInfo.LUCENE_SEARCH_PROVIDER, IndexType = TreeNode.OBJECT_TYPE, IndexAnalyzerType = SearchAnalyzerTypeEnum.StandardAnalyzer, StopWordsFile = "" }; // Creates new index settings // Specifies the content allowed in the index SearchIndexSettingsInfo indexSettings = new SearchIndexSettingsInfo() { ID = Guid.NewGuid(), // Configures the indexed content properties (for a Page index) ClassNames = "", // Allows indexing for all page types Path = "/%", SiteName = SiteContext.CurrentSiteName, Type = SearchIndexSettingsInfo.TYPE_ALLOWED, IncludeAttachments = false, IncludeCategories = false }; if (pageIndex != null && indexSettings != null && culture != null) { // Saves the index settings to the database and assigns them to the search index SearchIndexSettings settings = new SearchIndexSettings(); settings.SetSearchIndexSettingsInfo(indexSettings); pageIndex.IndexSettings = settings; // Saves the search index to the database SearchIndexInfoProvider.SetSearchIndexInfo(pageIndex); // Assigns the index to the current site SearchIndexSiteInfo.Provider.Add(pageIndex.IndexID, SiteContext.CurrentSiteID); // Assigns the 'en-US; culture to the index SearchIndexCultureInfo.Provider.Add(pageIndex.IndexID, culture.CultureID); // Creates a rebuild task for the index // The rebuild task will be processed as part of the next request handled by the application, // or by a scheduled task if the application is configured to handle search tasks using the scheduler. SearchTaskInfoProvider.CreateTask(SearchTaskTypeEnum.Rebuild, null, null, pageIndex.IndexName, pageIndex.IndexID); } ``` -------------------------------- ### Iterate DiscountSummary for Applied Discounts (Kentico Macro) Source: https://docs.kentico.com/13/e-commerce-features/managing-on-line-stores/discounts/working-with-buy-x-get-y-discounts This example shows how to iterate through the DiscountSummary collection in Kentico 13 to list the names and values of all applied Buy X Get Y discounts and product coupons for a specific order item. It uses Kentico macro syntax for conditional logic and looping. ```Kentico Macro {% result = ""; if (DiscountSummary.Any()) { result += "
    "; foreach (item in DiscountSummary) { result += "
  • " + HTMLEncode(Localize(item.Name)) + " (" + HTMLEncode(item.Value.Format(Currency.CurrencyFormatString)) + ")
  • " }; result += "
"; } return result; %} ``` -------------------------------- ### Adding Custom Data Example Source: https://docs.kentico.com/13/e-commerce-features/customizing-on-line-stores/integrating-google-analytics-enhanced-ecommerce Example demonstrating how to add custom data fields when mapping product information. ```APIDOC ## Adding Custom Data ### Description Custom data fields can be added to `GtmData` objects by passing an anonymous object to the `additionalData` parameter of `GtmProductHelper` and `GtmOrderHelper` methods. ### Example ```csharp // Assuming 'sku' is a SkuInfo object var productData = GtmProductHelper.MapSku(sku, new { category = "Apparel", custom_field = "some_value" }); // The resulting productData object will include 'category' and 'custom_field' ``` ``` -------------------------------- ### Get sites assigned to a user in Kentico Xperience 13 Source: https://docs.kentico.com/13/api/configuration/users Shows how to retrieve a user, then query for all SiteID's associated with that user from the UserSiteInfo table, and finally retrieve the corresponding SiteInfo objects. ```csharp // Gets the user UserInfo user = UserInfo.Provider.Get("NewUser"); if (user != null) { // Gets the sites to which the user is assigned var userSiteIDs = UserSiteInfo.Provider.Get().Column("SiteID").WhereEquals("UserID", user.UserID); var sites = SiteInfo.Provider.Get().WhereIn("SiteID", userSiteIDs); // Loops through the sites foreach (SiteInfo site in sites) { // Process the site } } ``` -------------------------------- ### Controller Action for Product Listing (C#) Source: https://docs.kentico.com/13/e-commerce-features/customizing-on-line-stores/integrating-google-analytics-enhanced-ecommerce An example controller action that retrieves products, prepares the ProductListViewModel, and passes it to the view. It demonstrates how to integrate the view models for product listing. ```csharp public ActionResult Index() { // Gets products of the product page type List products = pageRetriever.Retrieve(query => query .CombineWithDefaultCulture() .WhereTrue("SKUEnabled") .OrderByDescending("SKUInStoreFrom")) .ToList(); // Prepares the view model for the listing page var model = new ProductListViewModel(products.Select( product => new ProductListItemViewModel( product, GetPrice(product.SKU, shoppingService.GetCurrentShoppingCart()), product.Product.PublicStatus?.PublicStatusDisplayName)) ); // Displays the action's view with an initialized view model return View(model); } ``` -------------------------------- ### GET //global/ Source: https://docs.kentico.com/13/integrating-3rd-party-systems/xperience-rest-service/getting-data-using-rest Retrieves a specific global object of a given type by its code name or GUID. ```APIDOC ## GET //global/ ### Description Retrieves a specific global object of a given type using its code name or GUID. Global objects are not associated with any particular site. ### Method GET ### Endpoint `//global/` ### Parameters #### Path Parameters - **object type** (string) - Required - The type of the object to retrieve (e.g., `cms.emailtemplate`). - **object code name or guid** (string) - Required - The code name or GUID of the global object (e.g., `Blog.NotificationToModerators` or `607ed253-7842-48be-98d7-63e0714a6ad1`). ### Response #### Success Response (200) - **object** (object) - The requested global object. #### Response Example ```json { "object": { "id": 10, "codeName": "Blog.NotificationToModerators", "name": "Global Blog Notification" } } ``` ``` -------------------------------- ### Kentico Xperience REST Service GET Request Example Source: https://docs.kentico.com/13/integrating-3rd-party-systems/xperience-rest-service/getting-data-using-rest An example of a GET request to the Kentico Xperience REST service to retrieve user data. It includes the Authorization header for authentication and specifies the desired character encoding and content type. ```http GET http://localhost/Xperience/rest/cms.user/administrator HTTP/1.1 Authorization: Basic UmVzdENsaWVudDpNeVBhc3N3b3Jk Accept-Charset: utf-8 Content-Type: text\xml ``` -------------------------------- ### Example Source Database Query for Source Field Source: https://docs.kentico.com/13/external-utilities/kentico-xperience-import-toolkit/importing-data-from-external-sources An example of using a query against the source database to retrieve a value for import, dynamically using a macro expression. ```text # SELECT TOP 1 UserID FROM CMS_User WHERE UserName =‘{%SourceUserName%}’ ``` -------------------------------- ### Get Media File Relative Path (Kentico Macro) Source: https://docs.kentico.com/13/macro-expressions/reference-macro-methods Returns the permanent, relative URL path for a media library file using its GUID and file name. This method evaluates user permissions. Example: {% GetMediaFileRelativePath(FileGuid, FileName) %} ```kentico-macro {% GetMediaFileRelativePath(FileGuid, FileName) %} ``` -------------------------------- ### Get Attachment Relative Path (Kentico Macro) Source: https://docs.kentico.com/13/macro-expressions/reference-macro-methods Generates the relative URL path for a page attachment, identified by its GUID and file name. Optionally supports image variants. Must be called from the Url namespace. Example: {% Url.GetAttachmentRelativePath(AttachmentGUID, AttachmentName) %} ```kentico-macro {% Url.GetAttachmentRelativePath(AttachmentGUID, AttachmentName) %} ``` -------------------------------- ### Prepare and Display Product Listing View Model (C#) Source: https://docs.kentico.com/13/e-commerce-features/developing-on-line-stores/displaying-product-listings Prepares a collection of products for a product listing view and displays the view with the initialized view model. It uses ProductListItemViewModel to structure product data for the view. ```csharp IEnumerable productListing = products.Select( product => new ProductListItemViewModel( product, GetPrice(product.SKU, cart), pageUrlRetriever, product.Product.PublicStatus?.PublicStatusDisplayName)); // Displays the action's view with an initialized view model return View(productListing); } // Retrieves a ProductCatalogPrices instance that contains calculated price information for the given product private ProductCatalogPrices GetPrice(SKUInfo product, ShoppingCartInfo cart) { return priceCalculatorFactory .GetCalculator(cart.ShoppingCartSiteID) .GetPrices(product, Enumerable.Empty(), cart); } ``` -------------------------------- ### Create a New Site in Kentico Xperience 13 Source: https://docs.kentico.com/13/api/configuration/sites Demonstrates how to create a new site object, set its properties like display name, site name, status, and domain name, and then save it to the database using the SiteInfo.Provider.Set method. ```csharp // Creates a new site object SiteInfo newSite = new SiteInfo(); // Sets the site properties newSite.DisplayName = "New site"; newSite.SiteName = "NewSite"; newSite.Status = SiteStatusEnum.Stopped; newSite.DomainName = "127.0.0.1"; // Saves the site to the database SiteInfo.Provider.Set(newSite); ``` -------------------------------- ### GET //site// Source: https://docs.kentico.com/13/integrating-3rd-party-systems/xperience-rest-service/getting-data-using-rest Retrieves a specific object of a given type by its code name or GUID, assigned to a specified site. ```APIDOC ## GET //site// ### Description Retrieves a specific object of a given type by its code name or GUID, which is assigned to a particular site. ### Method GET ### Endpoint `//site//` ### Parameters #### Path Parameters - **object type** (string) - Required - The type of the object to retrieve (e.g., `cms.emailtemplate`). - **site name** (string) - Required - The name of the site the object belongs to (e.g., `samplesite`). - **object code name or guid** (string) - Required - The code name or GUID of the object (e.g., `Blog.NotificationToModerators` or `e431b7e6-9e6c-409d-a1d9-748cbf51b5d6`). ### Response #### Success Response (200) - **object** (object) - The requested object. #### Response Example ```json { "object": { "id": 15, "codeName": "Blog.NotificationToModerators", "name": "Blog Notification" } } ``` ``` -------------------------------- ### Create Media Library File in Kentico 13 Source: https://docs.kentico.com/13/api/content-management/media-libraries Demonstrates how to create a new file in a Kentico 13 media library. It involves getting the library, preparing file information, creating a MediaFileInfo object, setting its properties, and saving it using the MediaFileInfo.Provider.Set method. Dependencies include Kentico's CMS.MediaLibrary.Web.UI and CMS.IO namespaces. ```csharp // Gets the media library MediaLibraryInfo library = MediaLibraryInfo.Provider.Get("NewLibrary", SiteContext.CurrentSiteID); if (library != null) { // Prepares a path to a local file string filePath = @"C:\Files\images\Image.png"; // Prepares a CMS.IO.FileInfo object representing the local file CMS.IO.FileInfo file = CMS.IO.FileInfo.New(filePath); if (file != null) { // Creates a new media library file object MediaFileInfo mediaFile = new MediaFileInfo(filePath, library.LibraryID); // Sets the media library file properties mediaFile.FileName = "Image"; mediaFile.FileTitle = "File title"; mediaFile.FileDescription = "This file was added through the API."; mediaFile.FilePath = "NewFolder/Image/"; // Sets the path within the media library's folder structure mediaFile.FileExtension = file.Extension; mediaFile.FileMimeType = MimeTypeHelper.GetMimetype(file.Extension); mediaFile.FileSiteID = SiteContext.CurrentSiteID; mediaFile.FileLibraryID = library.LibraryID; mediaFile.FileSize = file.Length; // Saves the media library file MediaFileInfo.Provider.Set(mediaFile); } } ``` -------------------------------- ### Get Users in Role in Kentico 13 Source: https://docs.kentico.com/13/api/configuration/roles Retrieves all users belonging to a specific role within the current site in Kentico 13. It starts by fetching the role by name and site ID, then queries for the user IDs associated with that role, and finally retrieves the user information. This requires access to RoleInfo, UserRoleInfo, and UserInfo providers. ```csharp // Gets the role from the current site RoleInfo role = RoleInfo.Provider.Get("Rolename", SiteContext.CurrentSiteID); if (role != null) { // Gets the role's users var roleUserIDs = UserRoleInfo.Provider.Get().Column("UserID").WhereEquals("RoleID", role.RoleID); var users = UserInfo.Provider.Get().WhereIn("UserID", roleUserIDs); // Loops through the users foreach (UserInfo user in users) { // Process the user } } ``` -------------------------------- ### Set Up Controller Test with Mock Repository Source: https://docs.kentico.com/13/custom-development/writing-automated-tests/testing-mvc-controllers Configures a controller test environment using NUnit and NSubstitute. It fakes Kentico document types, creates a mock article repository, and injects it into the ArticleController, returning a predefined article for a specific ID. ```csharp private IArticleRepository articleRepository; private ArticleController controller; [SetUp] public void SetUp() { // Allows creating of articles without accessing the database Fake().DocumentType
(Article.CLASS_NAME); // Creates a mock article repository var article = TreeNode.New
() .With(a => a.Fields.Title = "TestArticle") .With(a => a.SetValue("DocumentID", 1)); articleRepository = Substitute.For(); controller = new ArticleController(articleRepository); articleRepository.GetArticle(1).Returns(article); } ``` -------------------------------- ### Create Product Page in Kentico Xperience 13 Source: https://docs.kentico.com/13/api/e-commerce/products Demonstrates creating a product page in Kentico Xperience 13, linking it to an existing SKU. It involves retrieving the SKU and a parent node in the content tree, then creating and saving a new product page node with custom field values. ```csharp // Gets the product (SKU) SKUInfo product = SKUInfo.Provider.Get() .WhereEquals("SKUName", "NewProduct") .TopN(1) .FirstOrDefault(); // Gets the root page of the products section in the content tree TreeNode parent = new DocumentQuery() .Path("/Products", PathTypeEnum.Single) .OnSite("MySite") .TopN(1) .Published() .PublishedVersion() .FirstOrDefault(); if ((parent != null) && (product != null)) { // Creates a new product page of the 'Custom.Product' type SKUTreeNode node = (SKUTreeNode)TreeNode.New("Custom.Product"); // Sets the product page properties node.DocumentCulture = LocalizationContext.PreferredCultureCode; string name = "Product page"; node.DocumentName = name; // Synchronize SKU name with document name in a default culture node.DocumentSKUName = name; // Sets a value for a field of the given product page type node.SetValue("ProductColor", "Blue"); // Assigns the product to the page node.NodeSKUID = product.SKUID; // Saves the product page to the database node.Insert(parent); } ``` -------------------------------- ### Get Carrier Configuration UI Element GUID in Kentico 13 Source: https://docs.kentico.com/13/e-commerce-features/customizing-on-line-stores/shipping-related-customizing/implementing-custom-shipping-carrier-providers Returns the GUID of a UI element used as the carrier's configuration tab. This tab is displayed when editing a carrier in the Store configuration application. Uses UIElementInfoProvider to retrieve the GUID. Returns Guid.Empty if no configuration tab exists. ```csharp using CMS.Modules; /// /// Returns the Guid of the carrier's configuration UI element, where moduleName is the code name /// of the module and elementName is the code name of the UIElement. /// public Guid GetConfigurationUIElementGUID() { UIElementInfo ui = UIElementInfoProvider.GetUIElementInfo(moduleName, elementName); return ui.ElementGUID; } ``` -------------------------------- ### Web Forms CSRF Example with Privilege Check (GET method) Source: https://docs.kentico.com/13/securing-websites/developing-secure-websites/cross-site-request-forgery-csrf-xsrf This C# code-behind example for a Web Forms page shows how user privileges can be checked when processing a request, in this case, using a UserID from the query string (GET method). While it includes a privilege check, it doesn't inherently prevent CSRF if the action itself is vulnerable. ```csharp using CMS.Membership; using CMS.Helpers; ... if (MembershipContext.AuthenticatedUser.CheckPrivilegeLevel(UserPrivilegeLevelEnum.GlobalAdmin)) { int userID = QueryHelper.GetInteger("UserID", 0); if (userID != 0) { Response.Write("I just deleted a user with id: " + userID); } } else { Response.Write("You don't have sufficient permissions to delete the user"); } ``` -------------------------------- ### Configure SameSite=None for Admin Cookies in .NET Startup Source: https://docs.kentico.com/13/developing-websites/working-with-cookies/configuring-cookie-samesite-mode Enables sending application cookies with SameSite=None, Secure, and Partitioned attributes, which is required for multi-domain Kentico Xperience environments when using preview mode. This configuration should be added after IServiceCollection.AddKentico in the ConfigureServices method. Both applications must use HTTPS. ```csharp public void ConfigureServices(IServiceCollection services) { services.AddKentico() // Required when hosting the administration application and the live site on different domains. // Sets the 'SameSite' attribute of system cookies to 'None' and pairs them with the 'Secure' and 'Partitioned' attributes // when sent under preview mode. Both applications also need to use a secure connection (HTTPS) // to ensure the cookies are not rejected. .SetAdminCookiesSameSiteNone(); ... } ``` -------------------------------- ### Page Selector Controller Class Example (C#) Source: https://docs.kentico.com/13/developing-websites/page-builder-development/selectors-for-page-builder-components Illustrates how to retrieve selected page GUIDs from the PageSelector component's 'Pages' property within a controller. It then uses an IPageRetriever to fetch the corresponding TreeNode objects based on these GUIDs. ```csharp private readonly IPageRetriever pagesRetriever; private readonly IComponentPropertiesRetriever componentPropertiesRetriever; public PageSelectorExample(IPageRetriever pagesRetriever, IComponentPropertiesRetriever componentPropertiesRetriever) { this.pagesRetriever = pagesRetriever; this.componentPropertiesRetriever = componentPropertiesRetriever; } public ActionResult Index() { // Retrieves the node GUIDs of the selected pages from the 'Pages' property List selectedPageGuids = componentPropertiesRetriever.Retrieve().Pages .Select(i => i.NodeGuid) .ToList(); // Retrieves the pages that correspond to the selected GUIDs List pages = pagesRetriever.Retrieve(query => query .WhereIn("NodeGUID", selectedPageGuids)) .ToList(); // Custom logic... return View(); } ``` -------------------------------- ### Load Grunt Plugins and Initialize Configuration Source: https://docs.kentico.com/13/developing-websites/developing-xperience-applications-using-asp-net-core/bundling-static-assets-of-builder-components This snippet shows how to load the necessary Grunt plugins (clean, concat, cssmin, terser) and initialize the Grunt configuration object. It's the foundational setup for the Gruntfile. ```javascript module.exports = function (grunt) { // Loads required Grunt plugins grunt.loadNpmTasks('grunt-contrib-clean'); grunt.loadNpmTasks('grunt-contrib-concat'); grunt.loadNpmTasks('grunt-contrib-cssmin'); grunt.loadNpmTasks('grunt-terser'); grunt.initConfig({ // Contains task definitions }); } ``` -------------------------------- ### Configure OWIN Startup for Xperience Membership (ASP.NET MVC) Source: https://docs.kentico.com/13/managing-users/user-registration-and-authentication/integrating-xperience-membership This C# code configures the OWIN startup class for an ASP.NET MVC project to integrate Xperience membership. It registers the Kentico UserManager and SignInManager, and configures the cookie authentication, including the login path and a custom provider for redirects. It also registers the authentication cookie with 'Essential' cookie level. ```csharp using System; using System.Web; using System.Web.Mvc; using Microsoft.Owin; using Microsoft.Owin.Security.Cookies; using Microsoft.AspNet.Identity; using Owin; using CMS.Helpers; using CMS.SiteProvider; using Kentico.Membership; // Assembly attribute that sets the OWIN startup class // This example sets the Startup class from the 'LearningKit.App_Start' namespace, not 'LearningKit.App_Start.Basic' used below // The active Startup class is defined in Startup.Auth.cs and additionally demonstrates registration of external authentication services [assembly: OwinStartup(typeof(LearningKit.App_Start.Startup))] namespace LearningKit.App_Start.Basic { public partial class Startup { // Cookie name prefix used by OWIN when creating authentication cookies private const string OWIN_COOKIE_PREFIX = ".AspNet."; public void Configuration(IAppBuilder app) { // Registers the Kentico.Membership identity implementation app.CreatePerOwinContext(() => KenticoUserManager.Initialize(app, new KenticoUserManager(new KenticoUserStore(SiteContext.CurrentSiteName)))); app.CreatePerOwinContext(KenticoSignInManager.Create); // Configures the authentication cookie UrlHelper urlHelper = new UrlHelper(HttpContext.Current.Request.RequestContext); app.UseCookieAuthentication(new CookieAuthenticationOptions { AuthenticationType = DefaultAuthenticationTypes.ApplicationCookie, // Fill in the name of your sign-in action and controller LoginPath = new PathString(urlHelper.Action("SignIn", "Account")), Provider = new CookieAuthenticationProvider { // Sets the return URL for the sign-in page redirect (fill in the name of your sign-in action and controller) OnApplyRedirect = context => context.Response.Redirect(urlHelper.Action("SignIn", "Account") + new Uri(context.RedirectUri).Query) } }); // Registers the authentication cookie with the 'Essential' cookie level // Ensures that the cookie is preserved when changing a visitor's allowed cookie level below 'Visitor' CookieHelper.RegisterCookie(OWIN_COOKIE_PREFIX + DefaultAuthenticationTypes.ApplicationCookie, CookieLevel.Essential); } } } ``` -------------------------------- ### Get Kentico Xperience 13 Settings Values (C#) Source: https://docs.kentico.com/13/api/configuration/settings Demonstrates how to retrieve the values of settings keys in Kentico Xperience 13. This includes site-specific settings like 'Page not found URL' and 'Application scheduler interval', as well as global settings like 'Scheduled tasks enabled'. The code utilizes the SettingsKeyInfoProvider and SiteContext classes. ```csharp // Note: To find the code names of setting keys, open the Modules application in Xperience, edit a module and view the Settings tab // Gets the value of the "Page not found URL" setting for the current site string pageNotFoundUrl = SettingsKeyInfoProvider.GetValue(SiteContext.CurrentSiteName + ".CMSPageNotFoundUrl"); // Gets the global value of the "Scheduled tasks enabled" setting bool scheduledTasksEnabled = SettingsKeyInfoProvider.GetBoolValue("CMSSchedulerTasksEnabled"); // Gets the value of the "Application scheduler interval" setting for the current site int schedulerInterval = SettingsKeyInfoProvider.GetIntValue(SiteContext.CurrentSiteName + ".CMSSchedulerInterval"); ``` -------------------------------- ### Register User with Email Confirmation (C#) Source: https://docs.kentico.com/13/managing-users/user-registration-and-authentication/enabling-user-registration Handles user registration, generates a confirmation token, prepares the confirmation URL, and sends a confirmation email. If registration fails, it displays the form with errors. It requires KenticoUserManager and UrlHelper. ```csharp // If the registration was not successful, displays the registration form with an error message if (!registerResult.Succeeded) { foreach (var error in registerResult.Errors) { ModelState.AddModelError(String.Empty, error); } return View(model); } // Generates a confirmation token for the new user // Accepts a user ID parameter, which is automatically set for the 'user' variable by the KenticoUserManager.CreateAsync method string token = await KenticoUserManager.GenerateEmailConfirmationTokenAsync(user.Id); // Prepares the URL of the confirmation link for the user (targets the "ConfirmUser" action) // Fill in the name of your controller string confirmationUrl = Url.Action("ConfirmUser", "EmailRegister", new { userId = user.Id, token = token }, protocol: Request.Url.Scheme); // Creates and sends the confirmation email to the user's address await KenticoUserManager.SendEmailAsync(user.Id, "Confirm your new account", String.Format("Please confirm your new account by clicking here", confirmationUrl)); // Displays a view asking the visitor to check their email and confirm the new account return View("CheckYourEmail"); } /// /// Action for confirming new user accounts. Handles the links that users click in confirmation emails. /// public async Task ConfirmUser(int? userId, string token) { IdentityResult confirmResult; try { // Verifies the confirmation parameters and enables the user account if successful confirmResult = await KenticoUserManager.ConfirmEmailAsync(userId.Value, token); } catch (InvalidOperationException) { // An InvalidOperationException occurs if a user with the given ID is not found confirmResult = IdentityResult.Failed("User not found."); } if (confirmResult.Succeeded) { // If the verification was successful, displays a view informing the user that their account was activated return View(); } // Returns a view informing the user that the email confirmation failed return View("EmailConfirmationFailed"); } } } ``` -------------------------------- ### Create and Save Product SKU and Page Source: https://docs.kentico.com/13/e-commerce-features/configuring-on-line-stores/configuring-products/importing-products/importing-products-using-the-api This C# code snippet demonstrates the process of creating a new product SKU, assigning it to a department, and saving it to the Kentico database. It also handles the creation of a corresponding product page, linking it to the SKU, and inserting it into the content tree. Error handling is included for both SKU and page creation. ```csharp SKUProductType = SKUProductTypeEnum.Product }; DepartmentInfo department = DepartmentInfo.Provider.Get(productData[3], siteId); if (department != null) { // Assigns the product to its department sku.SKUDepartmentID = department.DepartmentID; } try { // Saves the created product to the database SKUInfo.Provider.Set(sku); } catch (Exception ex) { Console.WriteLine($"Unable to create product '{sku.SKUName}'. See errors.txt for exception details."); File.AppendAllText("errors.txt", ex.ToString()); } // If the product was created successfully if (sku.SKUID > 0) { // Creates a product page and assigns the SKU var productDoc = (SKUTreeNode)TreeNode.New(productPageType.ClassName, tree); productDoc.DocumentName = sku.SKUName; productDoc.DocumentSKUName = sku.SKUName; productDoc.DocumentSKUDescription = sku.SKUDescription; productDoc.NodeSKUID = sku.SKUID; productDoc.DocumentCulture = DOCUMENT_CULTURE; try { productDoc.Insert(parentPage, true); Console.WriteLine($"Imported {sku.SKUName}."); } catch (Exception ex) { Console.WriteLine($"Unable to create page '{sku.SKUName}'. See errors.txt for exception details."); SKUInfo.Provider.Delete(sku); File.AppendAllText("errors.txt", ex.ToString()); } } ``` -------------------------------- ### Example Macro Condition for Report Subscription Source: https://docs.kentico.com/13/configuring-xperience/working-with-system-reports/subscribing-to-reports This example demonstrates how to use a macro condition to control when a report subscription email is sent. It checks if a specific A/B test is currently active based on its start time and the current date and time. This is useful for time-sensitive reports or campaigns. ```macro SiteObjects.ABTests["Home_en-US"].ABTestOpenFrom < DateTime.Now ``` -------------------------------- ### Update Multiple Buy X Get Y Discounts - Kentico API Source: https://docs.kentico.com/13/api/e-commerce/discounts Illustrates how to update multiple 'Buy X Get Y' discounts simultaneously in Kentico Xperience. This example retrieves all enabled discounts and modifies a common property before saving. ```csharp var discounts = MultiBuyDiscountInfoProvider.GetMultiBuyDiscounts(SiteContext.CurrentSiteID) .WhereTrue("MultiBuyDiscountEnabled"); foreach (MultiBuyDiscountInfo discount in discounts) { discount.MultiBuyDiscountEnabled = false; MultiBuyDiscountInfo.Provider.Set(discount); } ``` -------------------------------- ### Kentico 13: User Registration POST Action with Email Confirmation Source: https://docs.kentico.com/13/managing-users/user-registration-and-authentication/enabling-user-registration Handles the creation of new users via a POST request, generates an email confirmation token, and sends a confirmation email. It validates input, creates the user in the Xperience database, and logs any exceptions during the process. Dependencies include Microsoft.AspNetCore.Mvc, Microsoft.AspNetCore.Identity, CMS.Core, Kentico.Membership, and LearningKitCore.Models.Users.Registration. ```csharp using System; using System.Threading.Tasks; using Microsoft.AspNetCore.Mvc; using Microsoft.AspNetCore.Identity; using CMS.Core; using Kentico.Membership; using LearningKitCore.Models.Users.Registration; namespace LearningKitCore.Controllers { public class EmailRegisterController : Controller { private readonly SignInManager signInManager; private readonly ApplicationUserManager userManager; private readonly IMessageService messageService; public EmailRegisterController(ApplicationUserManager userManager, SignInManager signInManager, IMessageService messageService) { this.signInManager = signInManager; this.userManager = userManager; this.messageService = messageService; } /// /// Basic action that displays the registration form. /// public IActionResult RegisterWithEmailConfirmation() { return View(); } /// /// Creates new users when the registration form is submitted and sends the confirmation emails. /// Accepts parameters posted from the registration form via the RegisterViewModel. /// [HttpPost] [ValidateAntiForgeryToken] public async Task RegisterWithEmailConfirmation([FromServices] IEventLogService eventLogService, RegisterViewModel model) { // Validates the received user data based on the view model if (!ModelState.IsValid) { return View(model); } // Prepares a new user entity using the posted registration data // The user is not enabled by default ApplicationUser user = new ApplicationUser { UserName = model.UserName, Email = model.Email, FirstName = model.FirstName, LastName = model.LastName }; // Attempts to create the user in the Xperience database IdentityResult registerResult = IdentityResult.Failed(); try { registerResult = await userManager.CreateAsync(user, model.Password); } catch (Exception ex) { // Logs an error into the Xperience event log if the creation of the user fails eventLogService.LogException("MvcApplication", "UserRegistration", ex); ModelState.AddModelError(String.Empty, "Registration failed"); } // If the registration was not successful, displays the registration form with an error message if (!registerResult.Succeeded) { foreach (IdentityError error in registerResult.Errors) { ModelState.AddModelError(String.Empty, error.Description); } return View(model); } // Generates a confirmation token for the new user string token = await userManager.GenerateEmailConfirmationTokenAsync(user); // Prepares the URL of the confirmation link for the user (targets the "ConfirmUser" action) // Fill in the name of your controller string confirmationUrl = Url.Action(nameof(ConfirmUser), "EmailRegister", new { userId = user.Id, token = token }, protocol: Request.Scheme); // Creates and sends the confirmation email to the user's address ``` -------------------------------- ### Get Service Configuration UI Element GUID in Kentico 13 Source: https://docs.kentico.com/13/e-commerce-features/customizing-on-line-stores/shipping-related-customizing/implementing-custom-shipping-carrier-providers Returns the GUID of a UI element for a specific service's configuration tab. This tab appears when editing a shipping option. Similar to GetConfigurationUIElementGUID, it uses UIElementInfoProvider. Returns Guid.Empty if the service has no configuration tab. ```csharp Guid GetServiceConfigurationUIElementGUID(string serviceName) { // Implementation to get UI element GUID for the service return Guid.Empty; } ``` -------------------------------- ### GET /rest/cms.country (XML) Source: https://docs.kentico.com/13/integrating-3rd-party-systems/xperience-rest-service/getting-data-using-rest/examples-of-data-retrieved-via-the-rest-service Retrieves all _cms.country_ objects in XML format from the Kentico Xperience REST service. ```APIDOC ## GET /rest/cms.country ### Description Retrieves a list of all country objects in XML format. ### Method GET ### Endpoint ~/rest/cms.country ### Parameters #### Query Parameters - **format** (string) - Optional - Specifies the output format. Defaults to XML if not provided. ### Request Example ``` GET ~/rest/cms.country ``` ### Response #### Success Response (200) - **cms_countries** (object) - Contains a list of country objects. - **cms_country** (array) - An array of country objects. - **CountryID** (integer) - The unique identifier for the country. - **CountryDisplayName** (string) - The display name of the country. - **CountryName** (string) - The name of the country. - **CountryGUID** (string) - The globally unique identifier for the country. - **CountryLastModified** (string) - The timestamp of the last modification. - **CountryTwoLetterCode** (string) - The two-letter ISO code for the country. - **CountryThreeLetterCode** (string) - The three-letter ISO code for the country. - **TotalRecords** (object) - Contains the total number of records. - **TotalRecords** (integer) - The total count of country objects. #### Response Example ```xml 272 Afghanistan Afghanistan 12d61676-7541-4a4e-88f6-f02098b637fe 2013-10-21T14:20:12.293+02:00 AF AFG 246 ``` ``` -------------------------------- ### Set ApplicationPath for Virtual Directory Hosting (Startup Class) Source: https://docs.kentico.com/13/developing-websites/developing-xperience-applications-using-asp-net-core/deploying-and-hosting-asp-net-core-applications Sets the `SystemContext.ApplicationPath` property to the application's virtual directory path. This configuration should be done at the beginning of the `Configure` method to ensure correct path resolution for Xperience-specific middleware. ```csharp using CMS.Base; ... public void Configure(IApplicationBuilder app, IConfiguration configuration) { // Sets the root-relative application path to '/app' SystemContext.ApplicationPath = "/app"; ... } ``` -------------------------------- ### K# Method Calls (Infix and Prefix Notation) Source: https://docs.kentico.com/13/macro-expressions/macro-syntax Provides examples of calling K# macro methods using both infix notation (recommended for the first argument) and prefix notation. Infix is generally preferred for better IDE support. ```csharp // Returns "WORD" {% "word".ToUpper() %} ``` ```csharp // Returns "The sky is red on red planets" {% "The sky is blue on blue planets".Replace("blue", "red") %} ``` ```csharp // Alternative method calls with prefix notation (not supported by the autocomplete help) {% ToUpper("word") %} ``` ```csharp {% Replace("The sky is blue on blue planets", "blue", "red") %} ``` -------------------------------- ### Kentico Xperience REST Service - Get All Pages by Alias Path Source: https://docs.kentico.com/13/integrating-3rd-party-systems/xperience-rest-service/getting-data-using-rest Shows how to retrieve all pages that start with a specific alias path. This is useful for fetching hierarchical content structures or lists of items under a certain category. ```url /content/currentsite/en-us/all/news ``` ```url /content/site/samplesite/en-us/all/news ``` -------------------------------- ### Implement Custom Product Discount Source in C# Source: https://docs.kentico.com/13/e-commerce-features/customizing-on-line-stores/customizing-discounts This C# code snippet demonstrates the implementation of a custom product discount source by inheriting from the default ProductDiscountSource and implementing the IProductDiscountSource interface. It registers the custom class using the RegisterImplementation attribute. The GetDiscounts method overrides the base functionality to include default catalog and volume discounts, and then adds a custom 10% discount for registered users. ```csharp using System.Collections.Generic; using CMS; using CMS.Ecommerce; // Registers the custom implementation of IProductDiscountSource [assembly: RegisterImplementation(typeof(IProductDiscountSource), typeof(CustomProductDiscountSource))] public class CustomProductDiscountSource : ProductDiscountSource, IProductDiscountSource { /// /// Constructor with parameters that accept instances of services required by the ProductDiscountSource base class. /// public CustomProductDiscountSource(ICatalogDiscountSource catalogDiscountSource, IVolumeDiscountSource volumeDiscountSource, ISiteMainCurrencySource mainCurrencySource, ICurrencyConverterFactory currencyConverterFactory, IRoundingServiceFactory roundingServiceFactory) : base(catalogDiscountSource, volumeDiscountSource, mainCurrencySource, currencyConverterFactory, roundingServiceFactory) { } /// /// Creates a collection of product-level discounts that apply to a specified product. /// Additional data related to the price and purchase context is provided in the PriceParameters. /// public override IEnumerable GetDiscounts(SKUInfo sku, decimal standardPrice, PriceParameters priceParams) { var discountGroups = new List(); // Adds the default Xperience catalog and volume discounts (using methods from the ProductDiscountSource base class) AddCatalogDiscounts(discountGroups, sku, priceParams); AddVolumeDiscounts(discountGroups, sku, priceParams); // Adds a custom discount // The custom discount uses multiplicative stacking with any applied catalog or volume discounts // (i.e. the custom discount is calculated from the price reduced by other discounts) AddCustomDiscounts(discountGroups, sku, priceParams); return discountGroups; } /// /// Adds a custom discount for a specified product. /// private void AddCustomDiscounts(List discountGroups, SKUInfo sku, PriceParameters priceParams) { // Adds the discount only for customers who are registered users on the website if (priceParams.User != null) { // Creates a 10% custom discount (using a method from the ProductDiscountSource base class) IDiscount customDiscount = CreatePercentageProductDiscount("Discount for registered users", 0.1m, priceParams); // Adds the custom discount to the collection of overall product discounts var discountCollection = new DiscountCollection(new[] { customDiscount }); discountGroups.Add(discountCollection); } } } ```