XM Cloud - Getting component specific data

If you are binding your component with the layout response but feel that if a custom property can come in the layout response and you could bind that in your component.

But as you know you can not insert the custom property in the layout response without heavy customisation but we have a way to do so.

We can achieve this on component level using  useComponentProps and  getStaticProps: GetStaticComponentProps methods in XM cloud.

Lets understand this quickly.

You have a component like follows:

import type {
  ComponentRendering,
  Field,
  GetStaticComponentProps,
  ImageField,
  LayoutServiceData,
  LinkField,
} from '@sitecore-jss/sitecore-jss-nextjs';
import { useComponentProps } from '@sitecore-jss/sitecore-jss-nextjs';
type BlogIndexVariationOneProps = ComponentProps & {
  fields?: BlogIndexVariationOneFields;
};

function BlogIndexVariationOne({
  fields = {},
  rendering = {} as ComponentRendering,
}: BlogIndexVariationOneProps) {

const path = useComponentProps<string>(rendering?.uid);

return (
// your html here
)

}

In the component BlogIndexVariationOne we are passing the BlogIndexVariationOneProps. In this fields will be mapped from the layout response but rendering is worth to pay attention here that we will discuss the usage of it further in this blog.

Now assume that under this component you are returning the HTML with the data received in the fields object and additionaly you have a requirement to show the current page URL in any of the <div> tag also.

So as you know the current url will not work from  window.location.href or writing the same in the useEffect() or even useLocation() won't work until you don't wrap your component in the <Router> tag.

So how can we get the current url then? Here we will use the getStaticProps: GetStaticComponentProps method as shown below:

export const getStaticProps: GetStaticComponentProps = async (

  _rendering: ComponentRendering,
  layoutData: LayoutServiceData,
  context
) => {
  return context?.params?.requestPath
}

Here we are returning the requestPath provided by sitecore's context and it is returning the string type. 

Now how will we use this in our component? Here comes the role of rendering that we passed in the component in the line const path = useComponentProps<string>(rendering?.uid);. So rendering?.uid in the useComponentProps tells the component that something is being passed from getStaticProps: GetStaticComponentProps as string return type so use that.

And voilla, now you can use the request path in your code.

So in place of context?.params?.requestPath you can use your any API fetch if you want it to be fetched using this although the best practice for getting the API data is to use in the useEffect() but this is also one more way to use.

Thanks!

Sitecore powershell script to update rendering parameters and datasource item fields data

 We had one requirement to change the component's display on almost 1400 pages and doing so we had to follow following things:

1. Update the rendering parameters on the item

$parameters = [ordered]@{"DisplayContentInCard" = "1"; "ApplyBackground" = "1"; "AlignImageRight" = "1" }

$rendering | Set-RenderingParameter -Parameter $parameters | Set-Rendering -Item $pageItem -FinalLayout

 2. Update the datasource item's field data.

if ($datasource.StartsWith("local:")) {
                    $datasource = $datasource.Replace("local:", $pageItem.Paths.Path)
                }
                if ($datasource.StartsWith("/sitecore")) {
                    $datasourceItemNewVersion = Add-ItemVersion -Path "master:$($datasource)"
                    $datasourceItem = Get-Item -Path "master:$($datasourceItemNewVersion.FullPath)"
                    $quoteInitiation = "{0xxxxx0-FA49-445A-95FC-E3xxxxx1E3}"
                    if ($null -ne $dataSourceItem) {
                        $dataSourceItem.Editing.BeginEdit()
                        $dataSourceItem["quote"] = $quoteInitiation
                        $dataSourceItem["Link"] = ""
                        $dataSourceItem.Editing.EndEdit()
                        #$item = Get-Item -Path "master:$($dataSourceItem.FullPath)"
                        Publish-Item -Path "master:$($dataSourceItem.FullPath)" -PublishMode Smart -Target Edge
                        # Datasource item fields update - End
                    }
                    else {
                        Write-Host "Unable to process $($dataSourceItem.FullPath)"
                    }
                }
                else {
                    # this will execute when datasource is in GUID format
                    $datasourceItemNewVersion = Add-ItemVersion -Path "master:$($datasource)"
                    $datasourceItem = Get-Item "$($datasource)"
                    $quoteInitiation = "{03sss7FD0-FA49-445A-95FC-E35xxxxE3}"
                    if ($null -ne $dataSourceItem) {
                        $dataSourceItem.Editing.BeginEdit()
                        $dataSourceItem["quote"] = $quoteInitiation
                        $dataSourceItem["Link"] = ""
                        $dataSourceItem.Editing.EndEdit()
                        #$item = Get-Item -Path "master:$($dataSourceItem.FullPath)"
                        Publish-Item -Path "master:$($dataSourceItem.FullPath)" -PublishMode Smart -Target Edge
                        # Datasource item fields update - End
                    }
                    else {
                        Write-Host "Unable to process $($dataSourceItem.FullPath)"
                    }
                }

3. Update the main page with one droplink field to be set with the specific item.

$defaultProductOptionItemId = "{E2xxxxx-5DD0-4188-ABED-5Axxxxx56}";
                if ([string]::IsNullOrEmpty($pageItem["productionOption"])) {
                    $pageItem.Editing.BeginEdit()
                    $pageItem["productionOption"] = $defaultProductOptionItemId
                    $pageItem.Editing.EndEdit()
                    Publish-Item -Path "master:$($pageItem.FullPath)" -PublishMode Smart -Target Edge
                }

4. Export the info in the excel

    $props = @{
        InfoTitle       = "Quote Initiation."
        InfoDescription = "Processing for quote initiation of City pages for Auto owners."
        PageSize        = 25
    }

    $items |
    Show-ListView @props -Property @{Label = "Name"; Expression = { $_.DisplayName } },
    @{Label = "Id"; Expression = { $_.Id } },
    @{Label = "Template Name"; Expression = { $_.TemplateName } },
    @{Label = "Path"; Expression = { $_.ItemPath } }

Now the complete script is as follows:

# Product City Page - Auto

function ProcessProductLocationPage_Auto {
    $allItems = Get-ChildItem -Path "master://sitecore/content/SiteRoot/Home/States" -Recurse
    ForEach ($item in $allItems) {
        if ($item.TemplateName -match "City" -AND $item.Name -match "auto") {
            $newItemVersion = Add-ItemVersion -Path "master:$($item.FullPath)"
            $pageItem= Get-Item -Path "master:$($newItemVersion.FullPath)"
            try {
                # Update rendering parameters - Start
                $fityFiftyRenderingId = "{3FXXXE058-F909-4813-B4AA-92XXXXX5DE}"
                $defaultLayout = Get-LayoutDevice "Default"
                $renderings = Get-Rendering -Item $pageItem-Device $defaultLayout -FinalLayout
                $datasource = ""
                foreach ($rendering in $renderings) {
                    if ($rendering.ItemId -eq $fityFiftyRenderingId) {
                        $parameters = [ordered]@{"DisplayContentInCard" = "1"; "ApplyBackground" = "1"; "AlignImageRight" = "1" }
                        $rendering | Set-RenderingParameter -Parameter $parameters | Set-Rendering -Item $pageItem-FinalLayout
                        $datasource = $rendering.Datasource                
                    }
                }
                # Datasource item fields update - Start    
                # Check if the data source path has a special prefix
                if ($datasource.StartsWith("local:")) {
                    $datasource = $datasource.Replace("local:", $pageItem.Paths.Path)
                }
                if ($datasource.StartsWith("/sitecore")) {
                    $datasourceItemNewVersion = Add-ItemVersion -Path "master:$($datasource)"
                    $datasourceItem = Get-Item -Path "master:$($datasourceItemNewVersion.FullPath)"
                    $quoteInitiation = "{0ddddD0-FA49-445A-95FC-E35dddddE3}"
                    if ($null -ne $dataSourceItem) {
                        $dataSourceItem.Editing.BeginEdit()
                        $dataSourceItem["quote"] = $quoteInitiation
                        $dataSourceItem["Link"] = ""
                        $dataSourceItem.Editing.EndEdit()
                        #$item = Get-Item -Path "master:$($dataSourceItem.FullPath)"
                        Publish-Item -Path "master:$($dataSourceItem.FullPath)" -PublishMode Smart -Target Edge
                        # Datasource item fields update - End
                    }
                    else {
                        Write-Host "Unable to process $($dataSourceItem.FullPath)"
                    }
                }
                else {
                    # this will execute when datasource is in GUID format
                    $datasourceItemNewVersion = Add-ItemVersion -Path "master:$($datasource)"
                    $datasourceItem = Get-Item "$($datasource)"
                    $quoteInitiation = "{0dddddD0-FA49-445A-95FC-E3xxxxx31E3}"
                    if ($null -ne $dataSourceItem) {
                        $dataSourceItem.Editing.BeginEdit()
                        $dataSourceItem["quote"] = $quoteInitiation
                        $dataSourceItem["Link"] = ""
                        $dataSourceItem.Editing.EndEdit()
                        #$item = Get-Item -Path "master:$($dataSourceItem.FullPath)"
                        Publish-Item -Path "master:$($dataSourceItem.FullPath)" -PublishMode Smart -Target Edge
                        # Datasource item fields update - End
                    }
                    else {
                        Write-Host "Unable to process $($dataSourceItem.FullPath)"
                    }
                }    
       
                $defaultProductOptionItemId = "{Exxxx8D-5DD0-4188-ABED-5Axxxxx56}";
                if ([string]::IsNullOrEmpty($pageItem["prodOption"])) {
                    $pageItem.Editing.BeginEdit()
                    $pageItem["prodOption"] = $defaultProductOptionItemId
                    $pageItem.Editing.EndEdit()
                    Publish-Item -Path "master:$($pageItem.FullPath)" -PublishMode Smart -Target Edge
                }
           
            }
            catch [System.Net.WebException], [System.IO.IOException] {
                Write-Host "Unable to process item " $pageItem.FullPath
            }

            $pageItem
        }
    }
}
$items = ProcessProductLocationPage_Auto

if ($items.Count -eq 0) {
    Write-Host "Nothing found."
}
else {
    $props = @{
        InfoTitle       = "Quote Initiation."
        InfoDescription = "Your description here."
        PageSize        = 25
    }

    $items |
    Show-ListView @props -Property @{Label = "Name"; Expression = { $_.DisplayName } },
    @{Label = "Id"; Expression = { $_.Id } },
    @{Label = "Template Name"; Expression = { $_.TemplateName } },
    @{Label = "Path"; Expression = { $_.ItemPath } }
}

Write-Host "Script execution completed!"


Thanks!

Update sitecore rendering parameters using powershell

I had a requirement to update the rendering parameter using the PowerShell script so here is the code below:

Screenshot - 1:


Here is the script:

try {
    # rendering item id for which the parameters to be changed
    $renderingId = "{3F5DE058-F909-4813-B4AA-92F940FAE5DE}"
    # Item id on which rendering is available
    $itemId = "{E4A1AD6D-A6AD-47CE-8FF1-1783EE0082CA}"
    # Get item from master Database
    $item = Get-Item -Path "master:" -ID $itemId
    # This will be used to get the rendering info from Defaul layout as in Screenshot-1
    $defaultLayout = Get-LayoutDevice "Default"
    # Get all the renderings on this item that are available on the Final Layout
    $renderings = Get-Rendering -Item $item -Device $defaultLayout -FinalLayout
   foreach ($rendering in $renderings) {
    # Check for our specific rendering
      if ($rendering.ItemId -eq $renderingId) {
           Write-Host $rendering.ItemId
           # Set the parameters in key value format, where DisplayContentInCard is the rendering parameter field name and 1 is the value because in my case this is checkbox so setting it as true
           # Same is for other rendering parameter fields ApplyBackground and AlignImageRight
            $parameters = [ordered]@{"DisplayContentInCard" = "1"; "ApplyBackground" = "1"; "AlignImageRight" = "1" }
            # Set the parameters value and update on item  
            $rendering | Set-RenderingParameter -Parameter $parameters | Set-Rendering -Item $item -FinalLayout
   
              Write-Host "$($autoInsuranceItem.FullPath) - Item Id $($autoInsuranceItem.ID) - Rendering $($rendering.UniqueID)  $DatasourceItemPath - $($rendering.Datasource)"
      }
    }
}
catch [System.Net.WebException], [System.IO.IOException] {
    $item
}


Creating Solr core for sitecore using command prompt

We setup the solr cores using command “C:\solr8985\sc103solr-8.11.2\bin>solr.cmd create -c sitecore_sxa_web_index -d sitecore_configset” ...