Directives ========== The following directives may be used in XML schemas to configure Salesforce-related functionality. All the directives are in the ``http://namespaces.plone.org/salesforce/schema`` XML namespace. This namespace is usually configured at the top of the model like so:: ... Schema directives ----------------- These directives are valid as attributes of the ``schema`` tag. ``object`` Indicates the Salesforce object type to which this schema corresponds. Example:: ``container`` Indicates the path to a folder where items synced using this schema should be created. If the folder does not yet exist at the time of sync, it will be created. Example:: ``criteria`` Indicates additional criteria to limit which objects are retrieved from Salesforce. These criteria are added as a WHERE clause appended to the SOQL query passed to Salesforce. For example, the following schema definition:: will be translated into the following SOQL query:: SELECT Id FROM Contact WHERE Account.Name = 'Individual' Field directives ---------------- These directives are valid as attributes of the ``field`` tag. ``field`` Indicates the name of the corresponding field on the Salesforce object. The contents of the field will be mapped during a content sync. Example:: This states that the ``first_name`` field in Plone corresponds to the ``FirstName`` field in Salesforce. A field may also be retrieved from a parent object. For example:: This states that the ``org_name`` field should be pulled from the name of the Contact's related Account. ``converter`` Indicates the name of a custom converter that will be used to convert the value obtained from Salesforce into the value saved on the Plone object during sync. If no converter is specified, an attempt will be made to pick an appropriate one based on the field type. Example:: In this example, the Active__c field in Salesforce contains either the string 'true' or the string 'false', and we want to store a boolean in Plone. The implementation of the ``string_to_bool`` converter is as follows:: from five import grok from zope.schema.interfaces import IBool from collective.salesforce.content.interfaces import ISalesforceValueConverter from collective.salesforce.content.converters import DefaultValueConverter class StringToBoolConverter(DefaultValueConverter, grok.Adapter): """ Should convert 'true' and 'false' into boolean values """ grok.provides(ISalesforceValueConverter) grok.context(IBool) grok.name('string_to_bool') def toSchemaValue(self, value): if value: if value == 'true': return True return False ``relationship`` This is an advanced directive. Its main use is to allow a collection field (such as a List) to be populated with a series of objects from a Salesforce relationship. .. note:: The related objects will be stored as attributes of the main content type being synced, so this approach is not appropriate when the related objects should be represented as full-fledged content items in their own right in Plone. Example: Say we want to save a list dictionaries on a Contact, one for each of the contact's campaign memberships. This could be done using the following field on the Contact schema:: Campaign Memberships mypackage.interfaces.ICampaignMember In this example, ``mypackage.interfaces.ICampaignMember`` is a second schema based on the following model:: Campaign Name Campaign Status After a sync, this would result in each Contact's ``campaign_members`` attribute being set to a list of dictionaries, in the order returned by the Salesforce subquery. Each dictionary would have a ``name`` item and a ``status`` item. .. note:: The subschema may have its own ``criteria`` directive to limit which related objects are queried. The ``relationship`` directive can also be used in conjunction with the ``field`` directive in order to obtain a single field from each of the related objects. For example, syncing the following field would set the ``campaigns`` attribute of each Contact to a set of the names of each Campaign of which the Contact is a member:: Campaigns ``subquery`` This is an advanced directive. It allows the developer to inject an arbitrary subquery into the generated SOQL query to handle cases not supported by the other directives. Example:: would result in SOQL like:: SELECT Id, (SELECT Id FROM CampaignMembers WHERE HasResponded=true) FROM Contact .. note:: Notice the use of a custom converter via the ``converter`` directive. The ``subquery`` directive must always be used with a custom converter.