Posted by karens on February 6, 2008 at 4:15pm
We're talking about having fields that can retrieve and store their data either locally or remotely. Here's an idea of what might happen to the field settings array.
Field settings for a local field:
Array
(
[field_name] => field_caption
[type] => text
[type_name] => story
[module] => text
[db_storage] => 1
[db_source] => array
(
[type] => local
[text_processing] => 0
[max_length] =>
[allowed_values] =>
[allowed_values_php] =>
[table] => content_field_caption
[columns] => Array
(
[value] => Array
(
[type] => text
[size] => big
[not null] =>
[sortable] => 1
)
)
)
[display_settings] => Array
(
[label] => Array
(
[format] => above
)
[teaser] => Array
(
[format] => default
)
[full] => Array
(
[format] => default
)
[4] => Array
(
[format] => default
)
)
[widget_active] => 1
[required] => 0
[multiple] => 0
[active] => 1
[widget] => Array
(
[rows] => 1
[default_value] => Array
(
[0] => Array
(
[value] =>
)
)
[default_value_php] =>
[label] => Caption
[weight] => -2
[description] =>
[module] => text
[type] => text_textfield
)
)
Field settings for a remote node:
Array
(
[field_name] => field_caption
[type] => amazon_text
[type_name] => story
[module] => amazon_field
[db_storage] => 3
[data_source] => array
(
[type] => remote
[url] => amazon.com/feed/?item=%s&type=%s
[replacements] = array
(
[0] => field_caption[0]['value']
[1] = books
)
)
[display_settings] => Array
(
[label] => Array
(
[format] => above
)
[teaser] => Array
(
[format] => default
)
[full] => Array
(
[format] => default
)
[4] => Array
(
[format] => default
)
)
[widget_active] => 1
[required] => 0
[multiple] => 0
[active] => 1
[widget] => Array
(
[rows] => 1
[default_value] => Array
(
[0] => Array
(
[value] =>
)
)
[default_value_php] =>
[label] => Caption
[weight] => -2
[description] =>
[module] => text
[type] => text_textfield
)
)
Comments
A few remarks
A few remarks :
- This $field array is still largely defined by the structure of the field edit forms, and by legacy of the current and previous states of our meta data tables (content_node_field / content_node_field_instance). Notably it carries this outrageously misleading 'widget' key, that holds everything actually related to the 'instance' (no way we can make this early CCK 4.7 mixup get in core :-) )
- What is displayed here is the 'full-fledged' $field object internally processed by content.module. Not all of this is required nor relevant in $field 'objects' expected by CRUD API functions (currently
content_field_instance_create|update|delete($field)In order to have clearer programmer-facing $field definitions to use in the CRUD API, below is a (possibly wishful) attempt at getting away from legacy and structuring the $field 'object' in a way that would make sense if we started from scratch.
It obviously needs to be discussed and adjusted.
Array
(
[field_name] => 'field_caption' // * required
[field_type] => 'text' // * required
[type_name] => 'story' // * required
[required] => 0
[multiple] => 0
[text_processing] => 0
[max_length] => ''
[allowed_values] => ''
[allowed_values_php] => ''
[instance] => Array
(
[label] => 'Caption'
[weight] => -2
[description] => ''
[default_value] => Array ([0] => Array ([value] => '')
[default_value_php] => ''
[widget] => Array
(
[type] => 'text_textfield' // * required
[rows] => 1
)
[display] => Array
(
[label] => Array ([format] => 'above')
[teaser] => Array ([format] => 'default')
[full] => Array ([format] => 'default')
[rss] => Array ([format] => 'default')
)
// Below is internal stuff, automatically populated
[widget_module] => 'text'
[widget_active] => 1
)
// Below is internal stuff, automatically populated
[module] => 'text'
[active] => 1
[source] => array
(
[type] => 'local'
[table] => 'content_field_caption'
[columns] => Array
(
[value] => Array
(
[type] => 'text'
[size] => 'big'
[not null] => 0
)
)
)
)
Fields, instances, and node types
Your wishful-from-scratch field starts off with:
Array(
[field_name] => 'field_caption' // * required
[field_type] => 'text' // * required
[type_name] => 'story' // * required
I thought that after lengthy discussion we agreed that fields have a name (e.g body) and a field type (e.g. text) but do not have a "type_name" (e.g. story) because fields exist independently of any particular node type. A field instance is "field associated with a node type" and thus would have a [instance][type_name] (e.g. story) that it is applied to.
Also, I think it is confusing to use "field_caption" as the [field_name] example value and "Caption" as the [instance][label] example value. In the example it looks like [field_name] is the field's internal name (and table name when in per-table mode which, now, is always) and [instance][label] is the user-visible label displayed on form fields for a node of type [instance][type_name].
I've used "node" in several places where I actually mean "a Content object" (or "a Fieldable object" as I am thinking of renaming it) so as to be more concrete and understandable since we do not have a firm Content/Fieldable proposal on the table yet.
1 - about [type_name] =>
1 - about [type_name] => 'story' :
Agreed, this is exactly my point in http://groups.drupal.org/node/8703#comment-27025 below.
The $field array as it currently exists in CCK D4.7 to D6 is an unclear legacy mix of the 'field' and 'field instance' levels.
2- about [field_name] and [instance][label] :
I also think http://groups.drupal.org/node/8703#comment-27025 makes this more clear.
3- "Fieldable" sounds like a good idea, even though possibly a barbarism (but I'm probably not the best guy to evaluate that)
Also : arrays like this are
Also : arrays like this are called $field all over current CCK's code, while actually they describe a specific field instance.
I'm playing with the idea of representing the actual field, with all its instances, in an array like :
Array
(
[field_name] => 'field_caption'
[field_type] => 'text'
[required] => 0
[multiple] => 0
(... other field-level properties ... )
[instances] =>
[story] =>
[label] => 'Caption'
[weight] => -2
(... other instance-level properties for story ...)
[page] =>
[label] => 'Small description'
[weight] => 5
(... other instance-level properties for page ...)
Not exactly sure where this puts us API-wise, just wanted to make a note.
Multiple field instances per node type?
In this example, $field[instances] is keyed by node type. This leads to a question: Can a single field be applied to a node type more than once? Not as a multiple-value field but as 2+ single-value fields.
For example, suppose we have a node type representing an "Olympic Ice Skating Dance Performance." It has a field for the competitor's name, picture, bio, and video of the routine. It also has two ways to Fivestar vote on it: Technical Skill and Artistic Expression.
Can I create of field named "Vote" of type "fivestar" and assign it to the ice_performance node type twice, once with the caption "Technical Skill" and once with the caption "Artistic Expression"?
I think the answer is currently "no" and I'm fine with it staying that way. I need to create two separate fields of type "fivestar" and assign both to the node type; a single field can only be applied to each node type once. I'm just clarifying.
I have occassionally found
I have occassionally found this restriction annoying. It is easily worked around, but as long as we are redesigning stuff, and id be happy to remove it.
True. That's how CCK
True. That's how CCK currently works, a field can only appear once in a content type. I don't think we want to change this.
What we might want is a way to quickly create a new field based on an existing one, but two instances of the same field in the same type is not doable.
Fields values are curently stored in a (nid, vid, delta, value) table. In order to be able to distinguish the values from the different instances in the same (nid, vid), we'd need an additional 'instance_id' ? Brings a lot of code and conceptual complexity, and I'm not sure what this buys us compared to 'two separate fields'.
What I see in your "Skating Performance" example is actually two different fields, with different set of values. Notes on 'technical' and 'artistic' have no reason and IMO should not end up in the same pool of values.
Shared fields are primarily a 'pool of values'. Having a way to 'tie' fields so that they use the same settings is a different thing.
You're right that this would
You're right that this would be a good time to re-factor the $field array. And as I look at the last example it occurs to me that we should always use that construct. Then you can pick out the instance you want, see how many instances there are, etc. It might be a big improvement.
Merging the above comments
Merging the above comments together, here's a summerized proposal for fields / fields instance description arrays/objects.
Would probably be best as an attached text file, but we're not in the issue queue, so no file attachments in comments :-)
$field = Array (
[field_name] => 'field_caption'
[field_type] => 'text'
[required] => 0
[multiple] => 0
[text_processing] => 0
[max_length] => ''
[allowed_values] => ''
[allowed_values_php] => ''
[instances] => Array (
[story] => (.. a $field_instance array ...)
[page] => (.. a $field_instance array ...)
)
// Below is internal stuff, automatically populated
[module] => 'text'
[active] => 1
[source] => Array (
[type] => 'local'
[table] => 'content_field_caption'
[columns] => Array (
[value] => Array ([type] => 'text', [size] => 'big', [not null] => 0)
)
)
)
$field_instance = Array (
[label] => 'Small description'
[weight] => -2
[description] => 'Some helper text'
[default_value] => Array ([0] => Array ([value] => '')
[default_value_php] => ''
[widget] => Array (
[type] => 'text_textfield' // * required
[rows] => 1
)
[display] => Array (
[label] => Array ([format] => 'above')
[teaser] => Array ([format] => 'default')
[full] => Array ([format] => 'default')
[rss] => Array ([format] => 'default')
)
// Below is internal stuff, automatically populated
[widget_module] => 'text'
[widget_active] => 1
// Possibly needed so that you can't take an instance of a number field
// and assign it to a text field ?
[field_type] => 'text'
)