Sitecore Powershell: Alt Tags

Sitecore Powershell

As part of our ongoing work to improve the accessibility rating of our site, we needed to address the issue of lots of images not having ALT Tags in the media library. To achieve our goal I tested out the script below, before pointing it at the 100's of images in need of attention!

All credit to Adam Seabridge, who provided the solution and write up on the necessary configs required to get it working:

http://www.flux-digital.com/blog/auto-setting-alt-text-existing-new-images-in-sitecore-with-cognitive-services/

Adding it here for my own reference more than anything else.


$visionUrl = 'xxx'
$visionApiKey = 'xxx'
$visionFeatures = 'Description,Tags,Categories'
$rootPathOfImages = "/sitecore/media library/"
$testMode = $false
$secondsToWaitOnLimitError = 60
$successCount = 0
$errorCount = 0
$errorList = ""
$date = Get-Date
$formattedDate =$date.tostring('dd-mmm-yyyy-hhmmss')
$csvOutputFilePath = "C:\temp\Missing-Alt-Text-Report-$($formattedDate).csv"
$createCsv = $true
$csvResults = @()

# List of template ids to exclude from processing
$excludedTemplateIds = @(
    "{FE5DD826-48C6-436D-B87A-7C4210C7413B}", #media folder
    "{0603F166-35B8-469F-8123-E8D87BEDC171}", #pdf
    "{16692733-9A61-45E6-B0D4-4C0C06F8DD3C}", #doc
    "{7BB0411F-50CD-4C21-AD8F-1FCDE7C3AFFE}", #docx
    "{962B53C4-F93B-4DF9-9821-415C867B8903}", #unversioned file
    "{E76ADBDF-87D1-4FCB-BA71-274F7DBF5670}", #unversioned movie
    "{4F4A3A3B-239F-4988-98E1-DA3779749CBC}" #unversioned zip
)

# List of folder ids to exclude from processing
$excludedFolderIds = @(
    "{23FAF40D-6700-480C-BCAD-92E23F60634C}" #wffm folder
)

if($testMode){
    Write-Host -Foreground Yellow "Running in TEST MODE, no Alt Text will be set."
}
                    
Write-Host "Finding Images with Missing Alt Text in root folder: $($rootPathOfImages) ..."

cd $rootPathOfImages
$images = Get-ChildItem -Recurse . | Where-Object {
                                        ($excludedTemplateIds -notcontains $_.TemplateId) `
                                        -and ($excludedFolderIds -notcontains $_.ID) `
                                        -and ($excludedFolderIds -notcontains $_.Parent.ID) `
                                        -and ($excludedFolderIds -notcontains $_.Parent.Parent.ID) `
                                        -and ($excludedFolderIds -notcontains $_.Parent.Parent.Parent.ID) `
                                        -and ([string]::IsNullOrWhiteSpace($_.Fields["Alt"].Value)) `
                                    }

Write-Host -Foreground Green "$($images.Count) Images Found With Missing Alt Text"

$result = @()
$counter = 0
$mediaUrloptions = New-Object Sitecore.Resources.Media.MediaUrlOptions
$mediaUrloptions.Width = 1000
$mediaUrloptions.UseItemPath = 0

foreach ($image in $images)
{
    $counter+=1
    
    # Sitecore
    
    try{
        # Reading the binary of the image so that we could send it to the Computer Vision API
        Write-Host "Reading Image $($counter) of $($images.Count): $($image.ID) - $($image.Name) ...`n"
        $id = $image.ID
        $name = $image.Name
        $displayName = $image.Fields["__Display name"].Value
        $path = $image.ItemPath
        $success = $False
    
        $imageUrl = [Sitecore.Resources.Media.MediaManager]::GetMediaUrl($image, $mediaUrloptions)
        $url = $imageUrl -replace '/sitecore/shell', '' #fix to request image from published Site
        $url = "https://mysite.co.uk" + $url
        Write-Host "Downloading image: $url ...`n"

        $webClient = New-Object System.Net.WebClient
        $file = $webClient.DownloadData($url)
    }
    catch [System.Net.WebException]
    {
        $HttpStatusCode = $_.Exception.Response.StatusCode.value__
        $HttpStatusDescription = $_.Exception.Response.StatusDescription

        Write-Host -Foreground Red "Error Downloading Image: $($HttpStatusCode) - Http Status Description: $($HttpStatusDescription)"

        $errorCount +=1
        $errorList = $errorList + "$($id) - $($name) `n"
        continue
    }
    catch
    {
        Write-Host -Foreground Red "Error Downloading Image: $($id) - $($name) - Error Message: $($_.Exception.Message)"
        continue
    }

    # Computer Vision API
    
    do
    {
        try
        {
            if($file){
                Write-Host "Calling Endpoint: $($visionUrl)?visualFeatures=$($visionFeatures)&language=en"

                # Calling the Computer Vision API
                $response = Invoke-WebRequest `
                                 -Uri "$($visionUrl)?visualFeatures=$($visionFeatures)&language=en" `
                                 -Body $file `
                                 -ContentType "application/octet-stream" `
                                 -Headers @{"Ocp-Apim-Subscription-Key" = "$($visionApiKey)"} `
                                 -Method 'Post' `
                                 -ErrorAction Stop `
                                 -UseBasicParsing | ConvertFrom-Json

                # Tracking what image the response should be attached to
                $response | Add-Member -Name "id" `
                                       -MemberType NoteProperty `
                                       -Value "$($image.ID.ToShortID())"
                
                $altText = $response.description.captions[0].text
                Write-Host "Image Processed: $($image.Paths.FullPath)`n`n"
                if($altText){
				}
				else{
					$altText=$image.Name
				}
				
                if($altText){
                    
                    if($testMode){
                        Write-Host -Foreground Cyan "Alt Text Not set as in TEST MODE, but would be:" $altText
                    }
                    else 
                    {
                        # update Alt tag on image
                        $image.Editing.BeginEdit()
                        $image.Fields["Alt"].Value = $altText
                        $image.Editing.EndEdit()

                        Write-Host -Foreground Cyan "Alt Text Set To:" $altText
                        Write-Host "----------------------------------`n`n"
                    }
                    
                    $result += $response

                    $csvProperties = @{
                        ID = $id
                        Name = $name
                        DisplayName = $displayName
                        Path = $path
                        AltText = $altText
                    }

                    $csvResults += New-Object psobject -Property $csvProperties;

                    $success = $True

                    $successCount +=1

                }
                else{
                    Write-Host -Foreground Yellow "No Alt Text Returned For Image: $($id) - $($name)"
                    $errorCount +=1
                    $errorList = $errorList + "$($id) - $($name) `n"
                    break
                }
            }
            else{
                    Write-Host -Foreground Red "No Image Found In Sitecore For: $($id) - $($name)"
                    $errorCount +=1
                    $errorList = $errorList + "$($id) - $($name) `n"
                    break
                }
        }
        catch [System.Net.WebException]
        {
            $HttpStatusCode = $_.Exception.Response.StatusCode.value__
            $HttpStatusDescription = $_.Exception.Response.StatusDescription

            Write-Host -Foreground Red "Error Calling Computer Vision API: $($HttpStatusCode) - Http Status Description: $($HttpStatusDescription)"

            if($HttpStatusCode -eq "429"){
                Write-Host  -Foreground Magenta "Exceeded Computer Vision API limit. Waiting for $($secondsToWaitOnLimitError) seconds..."
                Start-Sleep -s $secondsToWaitOnLimitError
                Write-Host -Foreground Green "Resuming now..."
            }
            else{
                $errorCount +=1
                $errorList = $errorList + "$($id) - $($name) `n"
                break
            }
        }
        catch
        {
                Write-Host -Foreground Red "Error processing Image: $($id) - $($name) - Error Message: $($_.Exception.Message)"
                break
        }
    }
    while ($success -ne $True)
}

if($testMode){
    Write-Host -Foreground Yellow "TEST MODE complete."
}
Write-Host -Foreground Green "$($successCount) Images Successfully Processed"
Write-Host "$($errorCount) Errors Processing Images"

if($errorCount -gt 0){
    Write-Host -Foreground Red "Errors List"
    Write-Host -Foreground Red "-----------------------------"
    Write-Host -Foreground Red $errorList
}

if($createCsv -and $successCount -gt 0){
    Write-Host "Saving Report of Alt Text to: ${csvOutputFilePath}"
    $csvResults | Select-Object ID,Name,DisplayName,Path,AltText | Export-Csv -notypeinformation -Path $csvOutputFilePath
}

#Write-Host ($result | ConvertTo-Json -Depth 5)

Leave a Reply

Your email address will not be published. Required fields are marked *