Improve fields documentation #505

This commit is contained in:
Michael Stenta 2022-04-13 11:11:14 -04:00
commit 271caf0aea
3 changed files with 110 additions and 6 deletions

View File

@ -18,6 +18,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
- [Issue #3270561: Upgrade to gin beta](https://www.drupal.org/project/farm/issues/3270561)
- [Separate Docker image build from testing jobs in run-test.yml workflow #522](https://github.com/farmOS/farmOS/pull/522)
- [Merge test and release workflows into a unified delivery workflow #523](https://github.com/farmOS/farmOS/pull/523)
- [Improve fields documentation #505](https://github.com/farmOS/farmOS/pull/505)
### Fixed

View File

@ -15,7 +15,10 @@ If the field should be added to all bundles of a given entity type (eg: all log
types), then they should be added as "base fields" via
`hook_entity_base_field_info()`.
A `farm_field.factory` helper service is provided to make this easier:
A `farm_field.factory` helper service is provided to make this easier. For more
information on how this works, see [Field factory service](/development/module/services/#field-factory-service).
To get started, place the following in the `[modulename].module` file:
```php
<?php
@ -24,12 +27,14 @@ use Drupal\Core\Entity\EntityTypeInterface;
/**
* Implements hook_entity_base_field_info().
* NOTE: Replace 'mymodule' with the module name.
*/
function mymodule_entity_base_field_info(EntityTypeInterface $entity_type) {
$fields = [];
// Add a new string field to Log entities.
// 'log' specifies the entity type to apply to.
if ($entity_type->id() == 'log') {
// Options for the new field. See Field options below.
$options = [
'type' => 'string',
'label' => t('My new field'),
@ -39,6 +44,7 @@ function mymodule_entity_base_field_info(EntityTypeInterface $entity_type) {
'view' => 10,
],
];
// NOTE: Replace 'myfield' with the internal name of the field.
$fields['myfield'] = \Drupal::service('farm_field.factory')->baseFieldDefinition($options);
}
@ -56,10 +62,15 @@ then they should be added as "bundle fields" via
deprecated in favor of a core Drupal hook in the future. See core issue:
[https://www.drupal.org/node/2346347](https://www.drupal.org/node/2346347)
A `farm_field.factory` helper service is provided to make this easier. For more
information on how this works, see [Field factory service](/development/module/services/#field-factory-service).
The format for bundle field definitions is identical to base field definitions
(above), but the `bundleFieldDefinition()` method must be used instead of
`baseFieldDefinition()`.
To get started, place the following in the `[modulename].module` file:
```php
<?php
@ -67,12 +78,15 @@ use Drupal\Core\Entity\EntityTypeInterface;
/**
* Implements hook_farm_entity_bundle_field_info().
* NOTE: Replace 'mymodule' with the module name.
*/
function mymodule_farm_entity_bundle_field_info(EntityTypeInterface $entity_type, $bundle) {
$fields = [];
// Add a new string field to Input Logs.
// Add a new string field to Input Logs. 'log' specifies the entity type and
// 'input' specifies the bundle.
if ($entity_type->id() == 'log' && $bundle == 'input') {
// Options for the new field. See Field options below.
$options = [
'type' => 'string',
'label' => t('My new field'),
@ -82,6 +96,7 @@ function mymodule_farm_entity_bundle_field_info(EntityTypeInterface $entity_type
'view' => 10,
],
];
// NOTE: Replace 'myfield' with the internal name of the field.
$fields['myfield'] = \Drupal::service('farm_field.factory')->bundleFieldDefinition($options);
}
@ -126,6 +141,10 @@ Existing options can be overridden or removed by editing/deleting the entities
in the active configuration of the site. (**Warning** changing core types runs
the risk of conflicting with future farmOS updates).
Note that the file name is important and must follow a specific pattern. This
is generally in the form `[select_module_name].[select_field].[id].yml`. See
the examples for more info.
### Examples:
#### Flag
@ -140,11 +159,13 @@ dependencies:
enforced:
module:
- my_module
id: monitor
label: Monitor
id: organic
label: Organic
entity_types: null
```
Note that the file name is in the form `farm_flag.flag.[id].yml`.
The most important parts are the `id`, which is a unique machine name for
the flag, `label`, which is the human readable/translatable label that will be
shown in the select field and other parts of the UI, and `entity_types`, which
@ -194,6 +215,8 @@ id: field
label: Field
```
Note that the file name is in the form `farm_land.land_type.[id].yml`.
#### Structure type
The "Structure" module in farmOS provides a "Building" type like this:
@ -211,6 +234,8 @@ id: building
label: Building
```
Note that the file name is in the form `farm_structure.structure_type.[id].yml`.
#### Lab test type
The "Lab test" module in farmOS provides a "Soil test" type like this:
@ -228,6 +253,8 @@ id: soil
label: Soil test
```
Note that the file name is in the form `farm_lab_test.lab_test_type.[id].yml`.
#### ID tag type
ID tag types are similar to Flags, in that they have an `id` and `label`. They
@ -237,7 +264,7 @@ certain types of assets.
For example, an "Ear tag" type, provided by the "Animal asset" module, only
applies to "Animal" assets:
`animal/config/install/farm_flag.flag.ear_tag.yml`
`animal/config/install/farm_id_tag.id_tag.ear_tag.yml`
```yaml
langcode: en
@ -253,5 +280,7 @@ bundles:
- animal
```
Note that the file name is in the form `farm_flag.flag.ear_tag.[id].yml`.
If you want the tag type to apply to all assets, set `bundles: null`.
(or can it just be omitted?)

View File

@ -74,6 +74,80 @@ $all_inventory = \Drupal::service('asset.inventory')->getInventory($asset);
$gallons_of_fertilizer = \Drupal::service('asset.inventory')->getInventory($asset, 'volume', 'gallons');
```
## Field factory service
**Service name**: `farm_field.factory`
The field factory service provides two methods to make the process of creating
Drupal entity base and bundle field definitions easier and more consistent in
farmOS. This is used by modules that add [fields](/development/module/fields)
to [entity types](/development/module/entities).
Base fields are added to *all* bundles of a given entity type (eg: all logs).
Bundle fields are only added to *specific* bundles (eg: only "Input" logs).
Using this service is optional. It simply generates instances of Drupal core's
`BaseFieldDefinition` class or the Entity API module's `BundleFieldDefinition`
class, with farmOS-specific opinions to help enforce some consistency among
farmOS core and contrib modules. You can create instances of these field
definition classes directly instead of using the farmOS field factory service.
Or you can take the object produced by the service and customize it further
using standard Drupal field definition methods. This service is provided only
as a shortcut.
For more information on Drupal core's field definition API, see
[Drupal FieldTypes, FieldWidgets and FieldFormatters]([Drupal core field type](https://www.drupal.org/docs/drupal-apis/entity-api/fieldtypes-fieldwidgets-and-fieldformatters))
**Methods**:
`baseFieldDefinition($options)` - Generates a base field definition, given an
array of options (see below).
`bundleFieldDefinition($options)` - Generates a bundle field definition, given
an array of options (see below).
**Options**:
Both methods expect an array of field definition options. These include:
- `type` (required) - The field data type. Each type may require additional
options. Supported types include:
- `boolean` - True/false checkbox.
- `entity_reference` - Reference other entities. Additional options:
- `target_type` (required) - The entity type to reference (eg: `asset`,
`log`, `plan`)
- `target_bundle` (optional) - The allowed target bundle. For example,
a `target_type` of `asset` and a `target_bundle` of `animal` would
limit references to animal assets.
- `auto_create` (optional) Only used when `target_type` is set to
`taxonomy_term`. If `auto_create` is set, term references will be
created automatically if the term does not exist.
- `file` - File upload.
- `fraction` - High-precision decimal number storage.
- `geofield` - Geometry on a map.
- `image` - Image upload.
- `list_string` - Select list with allowed values. Additional options:
- `allowed_values` - An associative array of allowed values.
- `allowed_values_function` - The name of a function that returns an
associative array of allowed values.
- `string_long` - Unformatted text field of unlimited length.
- `text_long` - Formatted text field of unlimited length.
- `timestamp` - Date and time.
- `label` - The field label.
- `description` - The field description.
- `required` - Whether the field is required.
- `multiple` - Whether the field should allow multiple values. Defaults to
`FALSE`.
- `cardinality` - How many values are allowed (eg: `1` for single value
fields, `-1` for unlimited values). This is an alternative to `multiple`,
and will take precedence if it is set. Defaults to `1`.
Other options are available for more advanced use-cases. Refer to the
[FarmFieldFactory](https://github.com/farmOS/farmOS/blob/2.x/modules/core/field/src/FarmFieldFactory.php)
class to understand how they work.
For more information and example code, see [Adding fields](/development/module/fields).
## Group membership service
**Service name**: `group.membership`