6

I'm using the jsforce node package and I've tried the following:

conn.metadata.retrieve(
    {
        apiVersion: '38.0',
        unpackaged: {
            types: [
                {
                    members: ['Contact'],
                    name: 'Layout'
                }
            ]
        }
    }
).stream().pipe(fs.createWriteStream('contact.zip'));

Which results in the following XML:

<?xml version="1.0" encoding="UTF-8"?>
<Package xmlns="http://soap.sforce.com/2006/04/metadata">
    <types>
        <members>Contact</members>
        <name>Layout</name>
    </types>
    <version>38.0</version>
</Package>

I'm not sure where to retrieve all layouts from. I can do it via the describeLayouts() endpoint, but that seems to exclude the actual layout names which I definitely need.

I referenced this question and turned to the metadata file-based API calls which is shown above. I also did name: 'CustomObject' but it wasn't part of that response either. Any ideas?

Edit with REST API response: enter image description here

2 Answers 2

9

Use the Tooling API to query for the layouts:

SELECT FullName FROM Layout WHERE TableEnumOrId = 'Contact'

You can read more about the Tooling API REST Calls.

Here's the raw endpoint you would use:

/services/data/v38.0/tooling/query?q=SELECT+FullName+FROM+Layout+WHERE+TableEnumOrId=%27Contact%27

Example Output:

{
  "size" : 1,
  "totalSize" : 1,
  "done" : true,
  "queryLocator" : null,
  "entityTypeName" : "Layout",
  "records" : [ {
    "attributes" : {
      "type" : "Layout",
      "url" : "/services/data/v38.0/tooling/sobjects/Layout/00h50000000yfyCAAQ"
    },
    "FullName" : "Contact-Magical Happy Land"
  } ]
}
7
  • Yeah I was trying to give that a shot, but didn't see the actual name of the layout coming back, just the record type name Commented Jan 13, 2017 at 20:14
  • see my edit with the response from that endpoint. The names in this section are the record type names and I didn't see anything in the Layouts section to indicate a layout name Commented Jan 13, 2017 at 20:22
  • @MattAltepeter Found an answer in the tooling API. Take a peek.
    – sfdcfox
    Commented Jan 13, 2017 at 20:48
  • 4
    One caveat for future readers: selecting the FullName attribute can only be done when the result will return exactly one layout. Use Name instead to get all the layout names Commented Jan 20, 2017 at 18:10
  • 1
    @doga Yes, TableEnumOrId needs to be the Custom Object Id for custom objects. Use a query on CustomObject to find the Id that you need to use.
    – sfdcfox
    Commented Sep 17, 2018 at 8:15
2

Another way using only command line interface is to get the complete list of layouts and then filter and clean lines to get the complete list of layouts :

sfdx force:mdapi:listmetadata -m Layout -u myOrg | grep -i Fullname | grep SObjectName| cut -d "\"" -f 4
  • sfdx force:mdapi:listmetadata -m Layout -u myOrg gets the json with all layouts

  • grep -i Fullname removes all lines that are not the layouts names

  • grep SObjectName filters to keep only the ones concerning the object named SObjectName

  • cut -d "\"" -f 4 is kind of a hack to keep only what's between the 3rd and 4th double-quotes on the line, the layout name.

If you're using windows you should use something like git bash to run the command.

To retrieve all the layouts for a specific object, you could use this :

#initialize metadata variable
LAYOUTS=
#build the metadata list string
while read line; do
    LAYOUTS="Layout:$line,$LAYOUTS"
done <<< $(sfdx force:mdapi:listmetadata -m Layout -u myOrg | grep -i FullName | grep SObjectName | cut -d "\"" -f 4)
#remove final comma
LAYOUTS=${LAYOUTS::-1}
echo $LAYOUTS
#retrieve metadata
sfdx force:source:retrieve -m """$LAYOUTS""" -u myOrg
#   if you get a path error using sfdx with git bash, rather use :
#   $LOCALAPPDATA/sfdx/client/bin/sfdx.cmd force:source:retrieve -m """$LAYOUTS""" -u myOrg

Hope this can help

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .