I have a custom toolbox (.tbx) added to my favourites and so to find a specific tool within the toolbox, I 'd search (Tools > Favorites > [Type tool name] and then hopefully see the description of the tool in the results display but doesn't seem to display the metadata. Let's say I have a tool called 'Create Raster Extent Polygon' and I enter 'extent' in the search to get the result I need. It doesn't seem to display the tool description even though I have added information in all of the fields in the metadata page of the custom tool. Is there a way to show the tool description for custom tools similar to the inbuilt Esri ones? (See image for the custom tool example and the Esri tool that shows a nice tool description).
@MattHowe , do you know, that's so strange, i've been trying to work this one out, but it might be a bug. If you create a model or script in ArcMap, and edit the Summary field in the metadata, the description appears in tools and models. Also, all my old models made in ArcMap with a summary filled out display correctly in Pro. But i've just tried to make a new model/script in both ArcMap and Pro and none of the summaries appear below the tool in the search menu in Pro, but they appear in ArcMap in the Toolhelp sidebar.
It works for me...
@JohannesLindner which version of Pro are you using, and which Metadata standard?
@MattHowe have you tried a brand new toolbox in Pro? Just wandering if you're using a toolbox previously created in ArcMap?
Scratch that, i just tried with a brand new toolbox, created a blank script and edited the Summary in item description, and nothing.
Yeah I tried exactly the same thing and the description didn't show in the search results. Interested to see what @JohannesLindner reports back with re the metadata standard.
Sooooo....
I use the default metadata option, which seems to be "Item description".
Like you, I just tried creating a new python toolbox, editing the metadata of the default tool and searching for that tool. Didn't work:
Then I remembered: For my work, I programmed quite a few tools (e.g. input forms). Because the tools were in constant development, I didn't want to manually edit the metadata each time I changed some parameters. So I created a custom Parameter class and gave the Tool class some extra attributes and wrote a function that creates the tool help files automatically.
def Parameter(*args, **kwargs):
"""Wrapper for `arcpy.Parameter` which allows for a custom attribute `description`.
I can't just inherit from `arcpy.Parameter`, because arcpy is a wrapper for C classes and when I tried, it didn't work as expected. Using a wrapper class and forwarding all the methods and attributes would be too cumbersome. That's why this is a function that returns an `arcpy.Parameter`, using python's dynamic typing to add a custom attribute (which does noting in the underlying C code).
"""
try:
desc = kwargs["description"]
del kwargs["description"]
except KeyError:
desc = ""
p = arcpy.Parameter(*args, **kwargs)
p.description = desc
return p
# Toolbox.pyt
class Toolbox(object):
def __init__(self):
"""Define the toolbox (the name of the toolbox is the name of the
.pyt file)."""
self.label = "Toolbox"
self.alias = ""
# List of tool classes associated with this toolbox
self.tools = [Tool]
class Tool(object):
def __init__(self):
"""Define the tool (tool name is the name of the class)."""
self.label = "Tool"
self.canRunInBackground = False
# attributes for automatically creating the metadata
self.description = "This is a test tool."
self.usage = "You can't do anything with this tool."
self.search_keys = ["test", "another_tag"]
def getParameterInfo(self):
"""Define parameter definitions"""
params = [
## arcpy.Parameter(name="parameter", displayName="Parameter", datatype="GPString", parameterType="Optional", direction="Input"),
Parameter(name="parameter", displayName="Parameter", datatype="GPString", parameterType="Optional", direction="Input", description="This parameter does nothing."),
]
return params
def isLicensed(self):
"""Set whether tool is licensed to execute."""
return True
def updateParameters(self, parameters):
"""Modify the values and properties of parameters before internal
validation is performed. This method is called whenever a parameter
has been changed."""
return
def updateMessages(self, parameters):
"""Modify the messages created by internal validation for each tool
parameter. This method is called after internal validation."""
return
def execute(self, parameters, messages):
"""The source code of the tool."""
return
def create_tool_help_files():
import os
import datetime
import xml.etree.cElementTree as ET
today = datetime.datetime.now().strftime("%Y%m%d")
for tool in Toolbox().tools:
tool_instance = tool()
metadata = ET.Element("metadata")
dataIdInfo = ET.SubElement(metadata, "dataIdInfo")
# ESRI metadata
esri = ET.SubElement(metadata, "Esri")
ET.SubElement(esri, "CreaDate").text = today
ET.SubElement(esri, "CreaTime").text = today
ET.SubElement(esri, "ArcGISFormat").text = "1.0"
ET.SubElement(esri, "SyncOnce").text = "TRUE"
ET.SubElement(esri, "ModDate").text = today
ET.SubElement(esri, "ModTime").text = today
scaleRange = ET.SubElement(esri, "scaleRange")
ET.SubElement(scaleRange, "minScale").text = "150000000"
ET.SubElement(scaleRange, "maxScale").text = "5000"
# tool metadata
toolMeta = ET.SubElement(metadata,
"tool",
xmlns = "",
name = tool.__name__,
displayname = tool_instance.label,
toolboxalias = "")
ET.SubElement(toolMeta, "arcToolboxHelpPath").text = "c:\\program files\\arcgis\\pro\\Resources\\Help\\gp"
# Tags
searchKeys = ET.SubElement(dataIdInfo, "searchKeys")
tags = getattr(tool_instance, "search_keys", [])
for t in tags:
ET.SubElement(searchKeys, "keyword").text = str(t)
# Summary und Usage
summary = ET.SubElement(toolMeta, "summary").text = getattr(tool_instance, "description", "")
usage = ET.SubElement(toolMeta, "usage").text = getattr(tool_instance, "usage", "")
# parameter metadata
paramMeta = ET.SubElement(toolMeta, "parameters")
parameters = tool_instance.getParameterInfo()
if parameters is None:
parameters = []
for p in parameters:
param = ET.SubElement(paramMeta,
"param",
name = getattr(p, "name", ""),
displayname = getattr(p, "displayName", ""),
type = getattr(p, "parameterType", ""),
direction = getattr(p, "direction", ""),
datatype = getattr(p, "datatype", ""),
expression = getattr(p, "name", ""))
dialogReference = ET.SubElement(param, "dialogReference").text = getattr(p, "description", "n/a")
# Credit
idCredit = ET.SubElement(dataIdInfo, "idCredit").text = getattr(tool, "credit", "My employer\nMy Name\nMy mail address")
# some more general metadata
idCitation = ET.SubElement(dataIdInfo, "idCitation")
resTitle = ET.SubElement(idCitation, "resTitle").text = getattr(tool, "label", "")
distInfo = ET.SubElement(metadata, "distInfo")
distributor = ET.SubElement(distInfo, "distributor")
distorFormat = ET.SubElement(distributor, "distorFormat")
ET.SubElement(distorFormat, "formatName").text = "ArcToolbox Tool"
mdHrLv = ET.SubElement(metadata, "mdHrLv")
ET.SubElement(mdHrLv, "ScopeCd ", value = "005")
mdDateSt = ET.SubElement(metadata, "mdDateSt",Sync="TRUE").text = today
# write XML
directory = os.path.dirname(__file__)
toolbox_label = os.path.basename(__file__).replace(".pyt", "")
ET.ElementTree(metadata).write("{}.{}.pyt.xml".format(os.path.join(directory, toolbox_label), tool.__name__))
# execute the file from IDE to automatically create the tool metadata files
if __name__ == "__main__":
create_tool_help_files()
And it works:
Please don't ask me why...