mirror of
https://we.phorge.it/source/phorge.git
synced 2024-12-23 14:00:56 +01:00
Modernize CustomField documentation
Summary: Fixes T4102. Document all the new stuff that CustomField supports now, and all the applications you can use it with. Test Plan: Generated and read documentation. Reviewers: chad, btrahan Reviewed By: btrahan Subscribers: epriestley Maniphest Tasks: T4102 Differential Revision: https://secure.phabricator.com/D8541
This commit is contained in:
parent
8797c3ad0b
commit
7be740cd30
2 changed files with 187 additions and 64 deletions
187
src/docs/user/configuration/custom_fields.diviner
Normal file
187
src/docs/user/configuration/custom_fields.diviner
Normal file
|
@ -0,0 +1,187 @@
|
|||
@title Configuring Custom Fields
|
||||
@group config
|
||||
|
||||
How to add custom fields to applications which support them.
|
||||
|
||||
= Overview =
|
||||
|
||||
Several Phabricator applications allow the configuration of custom fields. These
|
||||
fields allow you to add more information to objects, and in some cases reorder
|
||||
or remove builtin fields.
|
||||
|
||||
For example, you could use custom fields to add an "Estimated Hours" field to
|
||||
tasks, a "Lead" field to projects, or a "T-Shirt Size" field to users.
|
||||
|
||||
These applications currently support custom fields:
|
||||
|
||||
| Application | Support |
|
||||
|-------------|---------|
|
||||
| Maniphest | Full Support |
|
||||
| Projects | Full Support |
|
||||
| People | Full Support |
|
||||
| Differential | Partial Support |
|
||||
| Diffusion | Limited Support |
|
||||
|
||||
Custom fields can appear in many interfaces and support search, editing, and
|
||||
other features.
|
||||
|
||||
= Basic Custom Fields =
|
||||
|
||||
To get started with custom fields, you can use configuration to select and
|
||||
reorder fields and to add new simple fields.
|
||||
|
||||
If you don't need complicated display controls or sophisticated validation,
|
||||
these simple fields should cover most use cases. They allow you to attach
|
||||
things like strings, numbers, and dropdown menus to objects.
|
||||
|
||||
The relevant configuration settings are:
|
||||
|
||||
| Application | Add Fields | Select Fields |
|
||||
|-------------|------------|---------------|
|
||||
| Maniphest | `maniphest.custom-field-definitions` | `maniphest.fields` |
|
||||
| Projects | `projects.custom-field-definitions` | `projects.fields` |
|
||||
| People | `user.custom-field-definitions` | `user.fields` |
|
||||
| Differential | Planned | `differential.fields` |
|
||||
| Diffusion | Planned | Planned |
|
||||
|
||||
When adding fields, you'll specify a JSON blob like this (for example, as the
|
||||
value of `maniphest.custom-field-definitions`):
|
||||
|
||||
{
|
||||
"mycompany:estimated-hours": {
|
||||
"name": "Estimated Hours",
|
||||
"type": "int",
|
||||
"caption": "Estimated number of hours this will take.",
|
||||
"required": true
|
||||
},
|
||||
"mycompany:actual-hours": {
|
||||
"name": "Actual Hours",
|
||||
"type": "int",
|
||||
"caption": "Actual number of hours this took."
|
||||
},
|
||||
"mycompany:favorite-dinosaur": {
|
||||
"name": "Favorite Dinosaur",
|
||||
"type": "text"
|
||||
}
|
||||
}
|
||||
|
||||
The fields will then appear in the other config option for the application
|
||||
(for example, in `maniphest.fields`) and you can enable, disable, or reorder
|
||||
them.
|
||||
|
||||
For details on how to define a field, see the next section.
|
||||
|
||||
= Custom Field Configuration =
|
||||
|
||||
When defining custom fields using a configuration option like
|
||||
`maniphest.custom-field-definitions`, these options are available:
|
||||
|
||||
- **name**: Display label for the field on the edit and detail interfaces.
|
||||
- **description**: Optional text shown when managing the field.
|
||||
- **type**: Field type. The supported field types are:
|
||||
- **int**: An integer, rendered as a text field.
|
||||
- **text**: A string, rendered as a text field.
|
||||
- **bool**: A boolean value, rendered as a checkbox.
|
||||
- **select**: Allows the user to select from several options, rendered
|
||||
as a dropdown.
|
||||
- **remarkup**: A text area which allows the user to enter markup.
|
||||
- **users**: A typeahead which allows multiple users to be input.
|
||||
- **date**: A date/time picker.
|
||||
- **header**: Renders a visual divider which you can use to group fields.
|
||||
- **edit**: Show this field on the application's edit interface (this
|
||||
defaults to `true`).
|
||||
- **view**: Show this field on the application's view interface (this
|
||||
defaults to `true`).
|
||||
- **search**: Show this field on the application's search interface, allowing
|
||||
users to filter objects by the field value.
|
||||
- **caption**: A caption to display underneath the field (optional).
|
||||
- **required**: True if the user should be required to provide a value.
|
||||
- **options**: If type is set to **select**, provide options for the dropdown
|
||||
as a dictionary.
|
||||
- **default**: Default field value.
|
||||
- **strings**: Allows you to override specific strings based on the field
|
||||
type. See below.
|
||||
|
||||
The `strings` value supports different strings per control type. They are:
|
||||
|
||||
- **bool**
|
||||
- **edit.checkbox** Text for the edit interface, no default.
|
||||
- **view.yes** Text for the view interface, defaults to "Yes".
|
||||
- **search.default** Text for the search interface, defaults to "(Any)".
|
||||
- **search.require** Text for the search interface, defaults to "Require".
|
||||
|
||||
Some applications have specific options which only work in that application.
|
||||
|
||||
In **Maniphest**:
|
||||
|
||||
- **copy**: When a user creates a task, the UI gives them an option to
|
||||
"Create Another Similar Task". Some fields from the original task are copied
|
||||
into the new task, while others are not; by default, fields are not copied.
|
||||
If you want this field to be copied, specify `true` for the `copy` property.
|
||||
|
||||
= Advanced Custom Fields =
|
||||
|
||||
If you want custom fields to have advanced behaviors (sophisticated rendering,
|
||||
advanced validation, complicated controls, interaction with other systems, etc),
|
||||
you can write a custom field as an extension and add it to Phabricator.
|
||||
|
||||
NOTE: This API is somewhat new and fairly large. You should expect that there
|
||||
will be occasional changes to the API requiring minor updates in your code.
|
||||
|
||||
To do this, extend the appropriate `CustomField` class for the application you
|
||||
want to add a field to:
|
||||
|
||||
| Application | Extend |
|
||||
|-------------|---------|
|
||||
| Maniphest | @{class:ManiphestCustomField} |
|
||||
| Projects | @{class:PhabricatorProjectCustomField} |
|
||||
| People | @{class:PhabricatorUserCustomField} |
|
||||
| Differential | @{class:DifferentialCustomField} |
|
||||
| Diffusion | @{class:PhabricatorCommitCustomField} |
|
||||
|
||||
The easiest way to get started is to drop your subclass into
|
||||
`phabricator/src/extensions/`, which should make it immediately available in the
|
||||
UI (if you use APC, you may need to restart your webserver). For example, this
|
||||
is a simple template which adds a custom field to Maniphest:
|
||||
|
||||
name=ExampleManiphestCustomField.php
|
||||
<?php
|
||||
|
||||
final class ExampleCustomField extends ManiphestCustomField {
|
||||
|
||||
public function getFieldKey() {
|
||||
return 'example:test';
|
||||
}
|
||||
|
||||
public function shouldAppearInPropertyView() {
|
||||
return true;
|
||||
}
|
||||
|
||||
public function renderPropertyViewLabel() {
|
||||
return pht('Example Custom Field');
|
||||
}
|
||||
|
||||
public function renderPropertyViewValue(array $handles) {
|
||||
return phutil_tag(
|
||||
'h1',
|
||||
array(
|
||||
'style' => 'color: #ff00ff',
|
||||
),
|
||||
pht('It worked!'));
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
Broadly, you can then add features by overriding more methods and implementing
|
||||
them. Many of the native fields are implemented on the custom field
|
||||
architecture, and it may be useful to look at them. For details on available
|
||||
integrations, see the base class for your application and
|
||||
@{class:PhabricatorCustomField}.
|
||||
|
||||
= Next Steps =
|
||||
|
||||
Continue by:
|
||||
|
||||
- learning more about extending Phabricator with custom code in
|
||||
@{article:libphutil Libraries User Guide};
|
||||
- or returning to the @{article: Configuration Guide}.
|
|
@ -1,64 +0,0 @@
|
|||
@title Maniphest User Guide: Adding Custom Fields
|
||||
@group userguide
|
||||
|
||||
How to add custom fields to Maniphest.
|
||||
|
||||
= Overview =
|
||||
|
||||
Maniphest provides some support for adding new fields to tasks, like an
|
||||
"cost" field, a "milestone" field, etc.
|
||||
|
||||
NOTE: Currently, these fields are somewhat limited. They primarily give you a
|
||||
structured way to record data on tasks, but there isn't much support for
|
||||
bringing them into other interfaces (e.g., querying by them, aggregating them,
|
||||
drawing graphs, etc.). If you have a use case, let us know what you want to do
|
||||
and maybe we can figure something out. This data is also exposed via the Conduit
|
||||
API, so you might be able to write your own interface if you want to do
|
||||
something very custom.
|
||||
|
||||
= Simple Field Customization =
|
||||
|
||||
If you don't need complicated display controls or sophisticated validation, you
|
||||
can add simple fields. These allow you to attach things like strings, numbers,
|
||||
and dropdown menus to the task template.
|
||||
|
||||
Customize Maniphest fields by setting `maniphest.custom-field-definitions` in
|
||||
your configuration. For example, suppose you want to add "Estimated Hours" and
|
||||
"Actual Hours" fields. To do this, set your configuration like this:
|
||||
|
||||
'maniphest.custom-fields' => array(
|
||||
'mycompany:estimated-hours' => array(
|
||||
'name' => 'Estimated Hours',
|
||||
'type' => 'int',
|
||||
'caption' => 'Estimated number of hours this will take.',
|
||||
'required' => true,
|
||||
),
|
||||
'mycompany:actual-hours' => array(
|
||||
'name' => 'Actual Hours',
|
||||
'type' => 'int',
|
||||
),
|
||||
)
|
||||
|
||||
Each array key must be unique, and is used to organize the internal storage of
|
||||
the field. These options are available:
|
||||
|
||||
- **name**: Display label for the field on the edit and detail interfaces.
|
||||
- **type**: Field type. The supported field types are:
|
||||
- **int**: An integer, rendered as a text field.
|
||||
- **text**: A string, rendered as a text field.
|
||||
- **bool**: A boolean value, rendered as a checkbox.
|
||||
- **select**: Allows the user to select from several options, rendered
|
||||
as a dropdown.
|
||||
- **remarkup**: A text area which allows the user to enter markup.
|
||||
- **users**: A typeahead which allows multiple users to be input.
|
||||
- **date**: A date/time picker.
|
||||
- **header**: Renders a visual divider which you can use to group fields.
|
||||
- **caption**: A caption to display underneath the field (optional).
|
||||
- **required**: True if the user should be required to provide a value.
|
||||
- **options**: If type is set to **select**, provide options for the dropdown
|
||||
as a dictionary.
|
||||
- **default**: Default field value.
|
||||
- **copy**: When a user creates a task, the UI gives them an option to
|
||||
"Create Another Similar Task". Some fields from the original task are copied
|
||||
into the new task, while others are not; by default, fields are not copied.
|
||||
If you want this field to be copied, specify `true` for the `copy` property.
|
Loading…
Reference in a new issue