CCK is an excellent way of customizing node types without so much as a line of custom PHP. However, if you wish the node to be part of some sort of dynamic process where nodes interact or are part of a process, you'll probably need to delve into widgets and fields a little bit deeper.
In this case, we wanted to link a node describing a petition with node describing a petitioner (name, address, email, etc.)- and we wanted to take advantage of CCK. We have a parent-child relationship, where at least one of the nodes must have a field pointing to it's counterpart. Fortunately, the nodereference field already exists, so all we need to do is supply it with data. We're going to do just that by supplying it with the last argument of the referring URL.
Start you module off by creating a .info file similar to this one:
<?php name = Auto Node Reference description = Supplies a Node ID based on the last argument of the referring URL dependencies = content nodereference package = CCK ?>
The dependencies are important- all CCK modules are dependant on the content module, and the nodereference module defines the field we wish to use.
Next, begin your .module file with hook_widget_info. This defines the label for your widget and the field types that it will work with. If you don't know the machine-readable name of the field, look at the hook_widget_info of a widget that already works with the field.
<?php <!--?php
function autonodereference_widget_info() {
return array(
'unimportanttext' =--> array( 'label' => 'Automatic URL Parent', 'field types' => array('nodereference'), ), ); } ?> ?>Next, you can set up custom settings for your widget to allow administrators to modify its behaviour, through hook_widget_settings. In this case, we're not implementing this, but if we were, it might look like this:
<?php <!--?php
function autonodereference_widget_settings($op, $widget) {
switch ($op) {
case 'form':
$form = array();
$form['argument'] = array(
'#type' =--> 'textfield', '#title' => t('Index of nid in URL'), '#default_value' => isset($widget['argument']) ? $widget['argument'] : 2, '#required' => TRUE, ); return $form; case 'validate': if (!is_numeric($widget['argument']) || intval($widget['argument']) != $widget['argument'] || $widget['argument'] <= 0) { form_set_error('argument', t('Index must be a positive integer.')); } break; case 'save': return array('argument'); } } ?> ?>The final hook to be written is hook_widget. It is responsible for preparing data for the form, drawing the form, and then preparing the data to be saved by the field. The most crucial part is understanding how the field expects the data to be presented. You'll need to look at the hook_field of the field you're writing for to determine how you will need to manipulate the data. It will look something like this:
<?php <!--?php
function autonodereference_widget($op, &$node, $field, &$node_field) {
switch ($op) {
case 'form':
$url = referer_uri();
$arguments = explode('/', $url);
$nid = array_pop($arguments);
$form = array();
$form[$field['field_name']] = array('#tree' =--> TRUE, '#weight' => $field['widget']['weight']); $form[$field['field_name']][0]['nid'] = array( '#type' => 'hidden', '#value' => isset($node_field[0]['nid']) ? $node_field[0]['nid'] : $nid, ); $form[$field['field_name']][0]['display'] = array( '#type' => 'item', '#title' => $field['widget']['label'], '#value' => isset($node_field[0]['nid']) ? $node_field[0]['nid'] : $nid, '#description' => t($field['widget']['description']), ); return $form; } } ?> ?>In this case, we don't need to massage the data, but if we did, we could do it by handling the 'prepare form values' or 'process form value' cases of $op. The naming of the form elements is crucial, as the data is saved to the $node_field variable accordingly.
Coding a widget is a relatively painless exercise that permits you to customize the CCK interface while writing an absolute minimum of code.
- Graphical user interface
- Widget
- GUI widget
- Technology Internet
- Node,Kentucky,United States
- Node
- php



Comments
Post cannot be referenced
Hi I tried using your widget above.
But the error shows that:
* parent_node : This post can't be referenced.
* The default value is invalid.
This is because my default value refers back to the node which exists before i click on save settings.
please kindly assist. Thanks!
Any help on this one?
Hi,
I am facing the same problem as the previous commenter.
Any help on this one?
-Tangan
The example code
The code above is not a complete, functioning module. The functions are show only as an example of what these hook_ functions would look like. In the case of autonodereference_widget above, it will only work if the nid to be referenced is the last argument of the referring URL (which relies on Clean URLs). Otherwise, the widget will pass an invalid nid and the CCK field (in this case, nodereference) will reject it with the "This post can't be referenced" message.
Field vs Widget
I've been looking at cck and I came across this post from a google search. I would've understood this post little better if I knew what the difference between a field and a widget is. Any hints?
Thanks.
Clear CCK Definitions
Indeed this isn't something that is particularly well documented in the CCK handbook, the closest thing I can find as a definition for you there is:
http://drupal.org/node/162247
People have also tried to explain it here:
http://groups.drupal.org/node/1986
http://groups.drupal.org/node/2876
Working from examples I've found I'd like to propose the following CCK definitions:
CCK Field - essentially a representation of the data as it is loaded and formatted to/from the database. Examples of field types include integer, decimal, text, link, e-mail.
CCK Widget - a customizable input control that is creates the user interface to add or edit the data that is sent to a field. Examples in CCK include textfield, select, check boxes, radio buttons and there is often more than one widget available for each field.
Logic can be inserted into a widget to search other tables or fields, you can define how it is going to be presented to the user, introduce AJAX, whatever. All of the stuff that is done before (or after) the data is saved as a field.
Each field type will have corresponding widgets. The form (widget) is in keeping with its contents (field type). Field types usually have a few widgets, because the same data can be entered in different ways.
For example (field type => widget):
text => text field, text area, select.
color => text field, color piker.
date => text field, calendar.
google search. I would've
google search. I would've understood this post little better if I knew what the difference between a field and a widget is. Any hints?
I have the same problem,
I have the same problem, wahts is the difference between a field and a widget?
Add new comment