A very poetic title, I must say. Today's problem is looking for buttons in Salesforce. I want to find all buttons for all objects. In addition, I want to know if any of them are Javascript buttons. I could manually go through each object in Setup and look at all of the buttons, but that doesn't sound like too much fun (actually that really sounds quite awful).
Finding anything code-, or configuration-, or metadata-related in Salesforce can be somewhat of a challenge. The Developer Console has a limited ability to find things in code via it's 'Search in Files' tool under the Edit menu. However, in my experience, this tool doesn't always find what I'm looking for. I've had better luck using Visual Studio Code to search in files after retrieving a metadata package from the org. The down-side to that is if you are not setup to use Visual Studio Code with Salesforce, there is a learning curve and legwork to be done. (Another blog post for another day) But, if you are setup in Visual Studio Code, and have the metadata from your org downloaded, then it's much easier to find what you're looking for using its global search.
So, how can we find buttons using the VS Code global search? Well, the buttons are defined in the object XML and can be found by searching for 'webLinks' (the name of the element that represents buttons, links and actions for the object). A quick search of 'webLinks' in the VS Code search turns up many hits.
Sounds like too much work to me. What I'm really looking for is something that will search through all of the object files for webLinks, maybe filter based on some other attributes of the webLinks elements, and then output useful information about the webLinks in a nice format.
I'm just going to jump to the next thought in my thought process, which was - since the metadata from Salesforce is XML, then it can be searched using XPath or XQuery. Well, my actual thought was "I think there is a way to query XML, so I'm going to search Google to see what it is," which lead me to XPath and XQuery. And, of course, the next question was "how do I run XPath or XQuery?"
Well... based on my previous blog posts, you can probably guess where I'm heading - PowerShell. Let's go with the idea that this can all be done using PowerShell, and break the problem down. (Side note: there is an XPath extension for Visual Studio Code. After a cursory glance at the readme, I decided to stick with PowerShell for now. https://marketplace.visualstudio.com/items?itemName=deltaxml.xslt-xpath)
1. We need to go through all of the object files (they're XML, despite having the extention .object)
2. We need to read each file in as XML
3. We need to use XPath/XQuery to find the <webLinks> elements in each file
4. We need to output useful attributes from each <webLinks> element into a format the is friendly for non-technical people to review.
Now we can see each basic element of the problem, which all appear to be pretty manageable. Time to unpack (hate that term) each one!
Looping Through the Object Files
First things first, we need to go through all of the object files. The basic idea I have is, for a given directory, go through that folder and all subfolders, find all of the files of type *.object (or really could be whatever extension), and open each one in turn as XML.
Going through a folder (and subfolders) and finding files of a certain extension can be done using the Get-ChildItem command [1].
Get-ChildItem -Path .\ -Include *.object -Recurse -ErrorAction SilentlyContinue
Read Each File in as XML
Use XPath to Find <webLinks> Elements
Output the Data
Footnotes:
1. https://devblogs.microsoft.com/scripting/use-windows-powershell-to-search-for-files/
2. https://devblogs.microsoft.com/scripting/powertip-use-powershell-to-easily-read-an-xml-document/
3. https://devblogs.microsoft.com/scripting/exploring-xml-document-by-using-the-xml-type-accelerator/