Tuesday, January 30, 2024

Automating Custom Business Logic in Sitecore CMS Using Custom Workflow Actions

If you need to execute custom business logic when an item is published in Sitecore CMS, the best way to achieve this is by creating a custom workflow action. This allows you to hook into Sitecore’s publishing process and inject your own logic when content is published, whether it involves modifying CMS content, interacting with external services, or any other tasks you may need to automate.

This guide will walk you through the steps of creating a custom workflow action in Sitecore, and we'll provide you with an example code snippet that you can adapt for your own business logic. The instructions below are applicable to all versions of Sitecore CMS.

Step 1: Set Up a Workflow Action in Sitecore

First, you need to create a workflow within Sitecore that triggers when an item is published. For this, you'll assign the Auto Publish action to the Published state. This action will be responsible for executing the workflow when content is published.

To integrate your custom business logic, you'll need to specify the C# class name and its associated assembly in the workflow. This class will contain the logic that should run when the item transitions to the Published state.



Step 2: Write Your Custom Action C# Class

In this step, you will write the C# code that defines the custom action for your workflow. This action could perform a wide range of tasks—such as modifying fields in the published item, calling external APIs, or executing other system operations as part of the publishing process.

Below is an example of how you can write a custom workflow action class in Sitecore:

using Sitecore; using Sitecore.Configuration; using Sitecore.Data; using Sitecore.Data.Items; using Sitecore.Diagnostics; using Sitecore.Globalization; using Sitecore.Publishing; using Sitecore.SecurityModel; using Sitecore.Web; using Sitecore.Workflows.Simple; using System; using System.Collections.Generic; using System.Collections.Specialized; using System.Linq; namespace ABC.Foundation.Configuration.Pipelines { public class CustomPublishAction { // Method that will be invoked during the workflow public void Process(WorkflowPipelineArgs args) { // Retrieve the item being processed Item dataItem = args.DataItem; Item innerItem = args.ProcessorItem.InnerItem; NameValueCollection urlParameters = WebUtil.ParseUrlParameters(innerItem["parameters"]); // Retrieve custom parameters for deep publishing, related items, etc. bool deep = GetDeep(urlParameters, innerItem); bool related = GetRelated(urlParameters, innerItem); Database[] targetDatabases = GetTargets(urlParameters, innerItem, dataItem).ToArray(); Language[] languages = GetLanguages(urlParameters, innerItem, dataItem).ToArray(); bool compareRevisions = IsCompareRevision(urlParameters, innerItem); // Ensure publishing settings are enabled and we have valid targets and languages if (!Settings.Publishing.Enabled || !targetDatabases.Any() || !languages.Any()) return; // Perform the publishing action PublishManager.PublishItem(dataItem, targetDatabases, languages, deep, compareRevisions, related); // Here you can add your custom logic, such as updating item fields or making API calls // Example: Get the current item's fields like Title and Description // You can further call external APIs or modify fields here } // Check if the publishing is deep (recursive) private bool GetDeep(NameValueCollection parameters, Item actionItem) => GetStringValue("deep", parameters, actionItem) == "1"; // Check if revision comparison is enabled private bool IsCompareRevision(NameValueCollection parameters, Item actionItem) => GetStringValue("smart", parameters, actionItem) == "1"; // Check if related items should be published private bool GetRelated(NameValueCollection parameters, Item actionItem) => GetStringValue("related", parameters, actionItem) == "1"; // Get the target databases for publishing private IEnumerable<Database> GetTargets(NameValueCollection parameters, Item actionItem, Item dataItem) { using (new SecurityDisabler()) { var sources = GetEnumerableValue("targets", parameters, actionItem).ToList(); // Default to the system publishing targets if no specific target is defined if (!sources.Any()) { Item targetsItem = dataItem.Database.Items["/sitecore/system/publishing targets"]; if (targetsItem != null) sources = targetsItem.Children.Select(child => child["Target database"]).Where(dbName => !string.IsNullOrEmpty(dbName)).ToList(); } foreach (var dbName in sources) { Database database = Factory.GetDatabase(dbName, false); if (database != null) yield return database; else Log.Warn($"Unknown database in PublishAction: {dbName}", this); } } } // Get the languages to be used for publishing private IEnumerable<Language> GetLanguages(NameValueCollection parameters, Item actionItem, Item dataItem) { using (new SecurityDisabler()) { IEnumerable<string> languageNames = Enumerable.Empty<string>(); if (GetStringValue("alllanguages", parameters, dataItem) == "1") { // If all languages are selected, fetch them from the system languages Item languagesItem = dataItem.Database.Items["/sitecore/system/languages"]; if (languagesItem != null) languageNames = languagesItem.Children.Where(child => child.TemplateID == TemplateIDs.Language) .Select(child => child.Name); } else { // Use the languages specified in the parameters languageNames = GetEnumerableValue("languages", parameters, actionItem); string itemLanguage = GetStringValue("itemlanguage", parameters, dataItem); if ((itemLanguage == "1" || itemLanguage == null) && !languageNames.Contains(dataItem.Language.Name)) yield return dataItem.Language; } // Yield the language objects for publishing foreach (var languageName in languageNames) { if (Language.TryParse(languageName, out var language)) yield return language; else Log.Warn($"Unknown language in PublishAction: {languageName}", this); } } } // Helper methods to fetch values from parameters or item fields private string GetStringValue(string name, NameValueCollection parameters, Item actionItem) { string value = actionItem[name]; return !string.IsNullOrEmpty(value) ? value : parameters[name]; } private IEnumerable<string> GetEnumerableValue(string name, NameValueCollection parameters, Item actionItem) { string value = actionItem[name]; if (!string.IsNullOrEmpty(value)) return value.Split('|', StringSplitOptions.RemoveEmptyEntries); string parameter = parameters[name]; return string.IsNullOrEmpty(parameter) ? Enumerable.Empty<string>() : parameter.Split(',', StringSplitOptions.RemoveEmptyEntries); } } }

Step 3: Test and Validate Your Custom Workflow Action

Once you've created the custom workflow action, it's time to test it. To do this, publish an item in Sitecore and verify if the business logic inside your C# class is executed properly. You can use debugging tools or log output to monitor the behavior of your custom action.

Ensure that any custom actions you’ve defined (e.g., updating fields, making API calls) are working as expected. You can refine and expand the logic as needed for more complex use cases.

By using a custom workflow action in Sitecore, you can automate complex tasks as part of the content publishing process. Whether you’re interacting with external systems, updating item fields, or performing other custom operations, this approach gives you the flexibility to integrate business logic directly into the publishing lifecycle.

Importance and Benefits of Custom Workflow Actions:

Creating custom workflow actions in Sitecore offers several significant advantages for your content management and publishing processes:

  1. Automate Complex Tasks: By adding custom business logic to the publishing pipeline, you can automate tasks that would otherwise require manual intervention. This helps save time, increase efficiency, and ensure consistency across your content management operations.

  2. Enhanced Flexibility: Sitecore’s custom workflow actions allow you to hook into the publishing process at any point and perform tasks tailored to your business needs. Whether you need to update item fields, notify external systems, or initiate downstream processes, you can customize the publishing workflow to fit your exact requirements.

  3. Improved Workflow Management: By utilizing custom actions, you ensure that your publishing workflow is aligned with the broader business logic of your organization. This means that publishing operations are not just about moving content to the live environment—they can also trigger necessary business functions automatically.

  4. Increased Control and Compliance: Custom workflow actions give you fine-grained control over the publishing process. For example, if certain content requires validation or approval from an external service before being made live, you can integrate this into the workflow. This ensures that your publishing process aligns with organizational requirements and complies with any internal or external regulations.

  5. Integration with External Systems: Custom workflow actions can be used to integrate Sitecore with external systems, such as CRMs, marketing automation platforms, or analytics tools. This makes it easier to trigger actions in other systems as part of the publishing process, ensuring your entire technology stack works together seamlessly.

  6. Streamlined User Experience: With automated processes, content managers and editors can focus on creating and curating high-quality content, rather than dealing with manual publishing steps. The workflow becomes more intuitive, and users can rely on automated actions to handle repetitive or complex tasks.

By creating a custom workflow action in Sitecore CMS, you unlock the potential to automate complex tasks during the content publishing process. Whether you’re modifying fields, integrating with external APIs, or managing other business operations, custom workflow actions provide the flexibility and control needed to streamline your publishing workflow.

This approach not only saves time and reduces errors but also enables you to scale your operations by automating repetitive tasks and ensuring that all your business logic is integrated directly into the Sitecore publishing lifecycle.

Start integrating custom business logic into your Sitecore publishing process today to enhance your content workflows, improve efficiency, and ensure seamless integration with external systems.

                        Happy learning and automating your Sitecore workflows!

Tuesday, January 16, 2024

How to Reset the Sitecore Admin Password: A Step-by-Step Guide

Have you forgotten your Sitecore admin password and want to reset it? If yes, follow this article to reset the password on SQL Server.



Sitecore is a powerful CMS used by many businesses to create and manage websites. One of the most important components of Sitecore is its admin interface, where you can manage the entire content pipeline, configurations, and more. However, there may be times when you forget your Sitecore admin password, which can create a lot of frustration. In this blog, we’ll walk you through the process of resetting the admin password in Sitecore.
Why Reset the Admin Password?
Sitecore’s admin interface is a crucial part of the system. If you’ve forgotten the password or if you are locked out due to security issues, you’ll need to reset it to regain full access. The password reset process can be done quickly, but there are several methods depending on your setup.
Method 1: Resetting the Password via Sitecore’s Database
The first method involves accessing Sitecore’s database directly. This is ideal when you can’t remember your admin credentials.
Steps:
  1. Log into SQL Server Management Studio (SSMS):
    Open SQL Server Management Studio and connect to the database where Sitecore is hosted. You’ll need the credentials to access the Sitecore database.
  2. Select the Sitecore Database:
    Once logged in, locate and expand the Sitecore database, typically named master.
  3. Find the User Table:
    Navigate to the Core database and open the AspNetUsers table. Here, you will find a list of all users in Sitecore, including the admin account.
  4. Update the Admin User’s Password:
    Locate the admin user, and update the password field using the following SQL command:
    sql:

    UPDATE [dbo].[AspNetUsers] SET PasswordHash = 'your_encrypted_password_here' WHERE UserName = 'admin'
    Note: You need to encrypt the new password (e.g., using a tool like bcrypt). Simply replacing the password as plain text will not work because Sitecore uses encrypted passwords.
  5. Save Changes and Exit:
    After the changes have been made, save them and exit the SQL Server Management Studio.
  6. Test Your New Password:
    Try logging into Sitecore using the admin account with the newly set password. If successful, you can now access the admin interface.
Method 2: Resetting Password via Sitecore PowerShell Extensions
If you have Sitecore PowerShell Extensions installed, you can reset the password more easily through the PowerShell console.
Steps:
  1. Open Sitecore PowerShell Console:
    In the Sitecore backend, navigate to the Sitecore PowerShell Console. You can usually find it in the Launchpad or under the System settings.
  2. Execute the Reset Command:
    Run the following PowerShell script to reset the admin password:
    powershell:

    $admin = Get-User -Username "admin" $admin | Set-UserPassword -Password "new_password"
    Replace "new_password" with the desired password.
  3. Save and Test:
    Once the command is executed successfully, try logging in to the Sitecore admin interface using the new password.
Method 3: Resetting via the Sitecore Admin Interface (if you have access)
If you still have access to Sitecore with an alternate user, you can reset the admin password from within the Sitecore interface.
Steps:
  1. Log in with an Alternate User Account:
    If you have another user with admin privileges, log into Sitecore using that account.
  2. Navigate to User Management:
    Go to the Security tab in the Sitecore interface and select User Manager.
  3. Locate the Admin User:
    Search for the admin user in the user management section.
  4. Reset the Password:
    You will see an option to reset the password. Enter the new password and save your changes.
  5. Log in with the New Password:
    Log out of the current session and try logging in with the admin user account using the newly reset password.
Method 4: Reset Password via Sitecore’s Web.config (Temporary Solution)
If you’re in a pinch and can’t reset the password through the database or PowerShell, you can use a temporary workaround via the web.config file.
Steps:
  1. Locate the web.config File:
    Go to the Sitecore installation directory and find the web.config file.
  2. Enable Administrator Login via Configuration:
    Add the following line under the <appSettings> section in web.config:
    xml:

    <add key="EnableAdminLogin" value="true" />
    This setting will allow the admin user to log in with the default password (b9b45dd3f2a04c7b87f5a22db37d6b9a).
  3. Log in and Change the Password:
    After adding the setting, you can log into Sitecore with the default password and change it to something more secure.
  4. Remove the Configuration Line:
    After successfully resetting the password, remove the line you added in web.config to ensure the security of your Sitecore instance.


                                                                Happy learning!

How to Create a Public Link Using the Sitecore Content Hub REST API

Creating a public link using the Sitecore Content Hub REST API is a straightforward process that enables you to share content externally whi...