Roll 1.x branch back before 1.1UI was merged
[project/features.git] / API.txt
1
2 Features 1.x API for Drupal 7.x
3 -------------------------------
4 This file contains documentation for two audiences: site builders interested in
5 creating and managing features and module developers interested in integrating
6 with the features module.
7
8
9 Terminology
10 -----------
11 - A **feature module** is a Drupal module that contains the `feature` key in its
12 `.info` file. This array describes the components that should be managed by
13 Features within the module.
14
15 - A **component** is a configuration object that can be exported. Examples: a
16 view, content type or CCK field instance.
17
18 - A **machine name** is a string identifier for a specific type of component and
19 should be unique within a single Drupal site. It should not be a numerically
20 generated serial id.
21
22 - An **exportable** component is one that can be used solely from a default hook
23 in code and without an instance in the database. For example, a view that lives
24 in code does not need an entry in the database in order to be used.
25
26 - A **faux-exportable** component is one that must exist in the database in
27 order to be used. Any exports of this component are used to create or
28 synchronize entries in the database that share the same machine name.
29
30
31 ### Component states
32
33 Features provides some infrastructure to determine the state of components on
34 the site. To determine the state of a component Features keeps track of three
35 things using an md5 hash of
36
37 - current code for the component. This is the configuration as actually
38 represented in code by a given feature.
39
40 - the most recent prior code state that differs from the current code state. For
41 example, if an `svn update` changes the configuration of a view, this stores the
42 code state *prior* to the update.
43
44 - The "normal" component state. This is the configuration represented by the
45 component as stored in the database or the default component (with any changes
46 introduced by `drupal_alter()`) if no database override exists.
47
48 Using these three values, Features determines a component to be in one of the
49 following five states:
50
51 - **Default** (`FEATURES_DEFAULT`) The object has no database entry or the
52 database entry matches the state of the component in code. This should be the
53 default state of components after installing a feature. Updating the component
54 can be done by altering the code definition directly.
55
56 - **Overridden** (`FEATURES_OVERRIDDEN`) The code remains constant but the
57 database object does not match the state of the component in code. Changes must
58 be reverted before the component can be updated from code.
59
60 - **Needs review** (`FEATURES_NEEDS_REVIEW`) The previous code state, database
61 state, and current code state all differ. This occurs most commonly when a user
62 changes one of her components and then pulls updates to her codebase. Since
63 there is no way to tell whether the code state or the database state is more
64 recent/valid, user input is necessary to resolve this state.
65
66 - **Rebuildable** (`FEATURES_REBUILDABLE`) This state only applies to
67 **faux-exportables** and indicates that the database component must and can be
68 safely updated from the code definition. The database entry does not match the
69 current code state but does match the previous code state. Features assumes that
70 in this scenario the user has made no substantive changes and the component can
71 be updated automatically.
72
73 - **Rebuilding** (`FEATURES_REBUILDING`) This state is rarely seen and only
74 applies to **faux-exportables.** This state is shown when a
75 `FEATURES_REBUILDABLE` component is *currently* being synced to the database.
76 Usually this operation is very fast and short lived. However, if the operation
77 is interrupted (e.g. the server goes down) this state will be seen until the
78 rebuild locking semaphore is cleared.
79
80
81 How a feature is generated
82 --------------------------
83 At a high level Features writes the code in a feature module using the following
84 steps:
85
86 1. An `.info` file describing the components that should be included in a
87 Feature is generated. It is either read from an existing feature or generated
88 through the Features UI.
89
90 2. Features converts the info file into an `$export` array which contains a list
91 of elements to be exported. Each component type is given a chance to add to the
92 export list as well as request that *other* components be given a second chance
93 to add to the `$export` array.
94
95 3. If any additional components have been queued up in the `$pipe` we repeat
96 step 2 for each of the queued component types.
97
98 4. Once a full `$export` array is populated each component renders items from
99 the `$export` array to PHP code as a exportable defaults hook.
100
101 5. Finally, Features writes the code into files and delivers it as a
102 downloadable package (UI) or writes it directly to a module directory (drush).
103
104 This workflow makes a variety of things possible:
105
106 ### Add components to a feature
107
108 Add the components to the `features` array in the feature's `.info` file and run
109 `drush features-update`. The same operation can be performed using the
110 *Recreate* page in the Features UI.
111
112 ### Remove components from a feature
113
114 Remove the corresponding component lines from the feature's `.info` file and run
115 `drush features-update`. The same operation can be performed using the
116 *Recreate* page in the Features UI.
117
118 ### Rename a component
119
120 Rename a component by changing its name in the feature's `.info` file and the
121 key and name property of the exported object in the appropriate `.inc` file in
122 the feature. Note that any references in other configuration objects to the
123 previous name should also be updated.
124
125
126 Integrating your module with the Features API
127 ---------------------------------------------
128 This section is for developers interested in adding Features-based management
129 for the configuration objects in their modules. From the perspective of
130 Features, there are a few different ways that modules store their configuration:
131
132 - In the `variable` table using `variable_set()`. If a module is using variables
133 for storing configuration, these variable settings can be exported with Features
134 by using the [Strongarm][1] module.
135
136   **Features integration:** Install the Strongarm module.
137
138 - Using a custom table with a serial ID for identifying configuration objects.
139 If this is the case, you will need to change your schema to use a string
140 identifier / machine name for each object.
141
142   **Features integration:** Fix your schema first, then see below.
143
144 - Using a custom table with a machine name identifier and custom exportables
145 handling (e.g. you have your own defaults hook handling and export generation).
146 If this is the case, you will need to implement many of the features hooks
147 yourself.
148
149   **Features integration:** `hook_features_api()`, `hook_features_export()`,
150 `hook_features_export_render()`, `hook_features_export_options()`,
151 `hook_features_revert()`.
152
153 - Using a custom table with CTools Export API integration. If this is the case,
154 Features will automatically have integration with your module. You can implement
155 any of the Features hooks in order to override the default CTools exportables
156 integration behavior.
157
158   **Features integration:** Automatically provided. You may implement any of the
159 Features hooks where you need further customization for your configuration
160 object.
161
162 If it isn't clear by now, we highly recommend using the [CTools][2] Export API
163 for adding exportables to your module. Stella has written a [fantastic HOWTO][3]
164 on using the CTools Export API that can get you started.
165
166
167 An overview of Features hooks
168 -----------------------------
169 Extensive documentation of the hooks provided by Features is available in
170 `features.api.php`. This section provides a short overview of each hook and its
171 role.
172
173 - `hook_features_api()` defines one or more component types that are available
174 to Features for export and a variety of settings for each type.
175 - `hook_features_export()` processes a list of components, detecting any
176 dependencies or further components
177 - `hook_features_export_options()` provides an array of components that can be
178 exported for a given type.
179 - `hook_features_export_render()` renders a set of components to code as a
180 defaults hook.
181 - `hook_features_revert()` reverts components of a feature back to their default
182 state.
183 - `hook_features_rebuild()` updates faux-exportable components back to their
184 default state. Only applies to faux-exportables.
185
186
187 [1]: http://drupal.org/project/strongarm
188 [2]: http://drupal.org/project/ctools
189 [3]: http://civicactions.com/blog/2009/jul/24/using_chaos_tools_module_create_exportables