The default "title" field in a node object is useful but not always appropriate. For some node types it would be preferable to rename the field for display to users (e.g., from "title" to "name" for a record of an organization or business), while in others the title might be best drawn from a combination of other fields (e.g., first_name and last_name fields,
for a record of an individual).

This patch enables two new alternatives for node titles:

renaming
The title field can be renamed, e.g., from "title" to "name".
substuting
Other fields can be substituted for the title field.

The functionality is implemented through a new proposed node hook, _title_field($op). There are two possible values for $op: "action" (either "rename" or "substitute") and "names" (a list of field names to be used in the title field).

Sample uses:

[?PHP

function example_title_field($node, $op) {
switch ($op) {
case 'action':
$return = 'rename';
break;
case 'names':
$return = array('Name');
}
return $return;
}

?]

In this case, since the requested action is "rename", the title field would be labelled "Name" (instead of "Title") in node add and edit forms for nodes of type "example".

[?PHP

function example_title_field($node, $op) {
switch ($op) {
case 'action':
$return = 'substitute';
break;
case 'names':
$return = array('first_name', 'last_name');
}
return $return;
}

?]

In this case, no "Title" field would be displayed in node add or node edit forms of node type "example". Instead, the fields "first_name" and "last_name" would be concatenated to form a title.

Implementing this patch would significantly increase the flexibility of the node system, making it feasible to store information of many types not currently supported because they don't have a "title" attribute.

Support from Acquia helps fund testing for Drupal Acquia logo

Comments

Dries’s picture

This is best accomplished through the existing nodeapi hook, using a separate module.

nedjo’s picture

Thanks for the suggestion. I did look for a way to accomplish this through _nodeapi (and other existing hooks), but couldn't see how. The "title" field is hard-coded into node.module. The _nodeapi hook allows various types of manipulations, but not, so far as I could see, changes to elements that have been generated by, e.g., form_textfield() calls.

Are there possibilities I'm missing? Other approaches? Any specific suggestions as to means we could use to change the hard-coded "title" field?

nedjo’s picture

FileSize
741 bytes

Drawing on Dries's suggestion, I've substantially revised this patch to enable node title field customization with only three additional lines of code in node.module.

In place of the existing line in function node_form()


  $output .= form_textfield(t('Title'), 'title', $edit->title, 60, 128, NULL, NULL, TRUE);

the patch substitutes a the following:

  $title = variable_get('node_titlefield_'. $edit->type, 'Title');
  if(!($title == 'none')) {
    $output .= form_textfield(t($title), 'title', $edit->title, 60, 128, NULL, NULL, TRUE);
  }

With this change in place, node modules will be able to override the standard node title label by setting a variable, node_titlefield_nodetype, where nodetype is the type of node. This could be done, e.g., in a _settings hook, so that the first time settings were accessed the module would set the variable:

 if (variable_get('node_titlefield_example', '') == '') {
   // since none is already set, set this variable
   variable_set('node_titlefield_example', 'Name');
   drupal_set_message('Example module initialization completed.');
 }

The special value 'none' would suppress the title field altogether in node forms, used as follows:

 if (variable_get('node_titlefield_example', '') == '') {
   // since none is already set, set this variable
   variable_set('node_titlefield_example', 'none');
   drupal_set_message('Example module initialization completed.');
 }

In this case, a _validate hook would be used to set the title field value. Assuming a module where a first name-last name combination was to be used for a title:

function example_validate(&$node) {
  if(!(isset($node->title))) {
    $node->title = $node->first_name . ' ' . node->last_name;
  }
}

In short, this three-line addition to the node.module would significantly increase the flexibility of the node system by removing the hard-coded 'Title' field in node add and edit forms and instead enabling custom labelling or concatenation of the field from other sources.

moshe weitzman’s picture

I like this functionality. But the implementation still seems unclean. I would prefer to simply remove the 'title' form field from node_form() and require that modules present this field in whatever way they please. in some cases, they will use a hidden form field because no customer interaction is required. This causes a break with backward compatibility, but cleanliness is facored over compatibilityness (when you must choose).

I'm moving this back to 'Active', since I don't think this patch is committable as is.

nedjo’s picture

FileSize
830 bytes

Thanks for looking at this. The suggestion - dropping the title field altogether and leaving this for module authors - has the advantage of simplicity. However, this change would imply significant new work as it would would require all or nearly all existing modules - core and contributed - be modified. While I think enabling title field customization is important for Drupal as a whole, and while this is a change I need for two modules I'm working on, I'm not immediately convinced that the benefits of this change justify this cost. Also, in most cases, the present title field works fine, so keeping it as a default option would I feel be desirable.

Hence the following patch. In place of my (poorly conceived) initial hook proposals, above, this patch introduces a single very straightforward new node hook, _title_field. By setting this hook to return FALSE, node modules authors will suppress the default title field, and be free therefore to substitute what they wish or need. Returning TRUE, or not using the hook, will result in the default title field being used.

Sample usage:

function example_title_field() {
  return FALSE;
}

This is, I feel, a much better solution than the previous two I suggested--proof, if it's true, that the Drupal issue system works!

nedjo’s picture

Are there any objections to or issues raised by this small patch (introducing a new hook to make the title field optional in node forms)? If not, can it be applied?

Anonymous’s picture

I think I agree with Moshe's opinion that this should be accomplished by having node modules display the title field. In any event, this is a new feature and shouldn't go in during the feature freeze for 4.5.

ccourtne’s picture

+1 for just moving the title field to be a responsibility of the implementing module instead of node_form. There is already to some extent "hook overload", in addition there may be several modules which don't want to even display a title module. Why add that only fixes some of the problems just to have to remove it later when you make a fix that address the whole problem.

nedjo’s picture

FileSize
636 bytes

Thanks for comments. As per feedback, the attached patch removes the title field from node forms, leaving this instead to node modules.

Understood that possible approval of this patch this will need to wait until code unfrozen.

moshe weitzman’s picture

please patch all core node modules as well.

nedjo’s picture

Title: Enable customizing of "title" field on nodes » Enable customizing of "Title" field on node forms
FileSize
4.29 KB

Good point Moshe. This patch of node.module plus all core node modules simply moves the title field out of node.module and into the node modules, enabling (if desired) customization of the title field by a module. Patches to contributed modules will in most cases be as simple as adding the line

  $output = form_textfield(t('Subject'), 'title', $node->title, 60, 128, NULL, NULL, TRUE);

at the beginning of a typename_form() function (and, if necessary changing an existing $output = to $output .=). In the attached patch, I've customized the title field for only one of the node types, calling the title of a forum topic the "Subject". We could consider calling the title of a blog a "Subject" or "Topic" as well.

I feel this is a good solution (thanks for the feedback and discussion) and, for minimal work (minor updates to contributed modules), will have the significant benefit of enabling flexibility in content types beyond those that have "title" attributes.

nedjo’s picture

Ability to customize title as provided in this patch was requested here:

When adding/editing, the 'title' field is manditory, which is fine. Except that its label is hardcoded to 'title'. A custom node modelling, say, a 'Company' would much rather this field be presented to the user as 'Company Name'.

nedjo’s picture

Here's another patch that's sat for months without being either applied or turned down, although there was expressed support and, after several iterations, it addressed all issues that had been raised. The point is to remove the hard-coded "Title" field - inapprioriate for many node types, e.g., companies - from node forms, instead allowing node modules to treat this as appropriate (e.g., a "Subject", "Name" or "Topic", or nothing at all).

Are there problems with this approach that were not raised? Is there a reason this wasn't accepted?

Steven’s picture

nedjo: if you read the backlog you can see that this feature was delayed for after the 4.6 release.

I've customized the title field for only one of the node types, calling the title of a forum topic the "Subject".

This is really inconsistent, as what you call the title of a blog, story or forum node is purely subjective. "Subject" "Topic" and "Title" are pretty much interchageable and any subtle differences will surely be eroded by translation. The only thing I can agree on so far is naming a polls' title "Question".

nedjo’s picture

Thanks for the note. I'm not sure what you mean by the "backlog". Where would I find this? I agree that a "Question" field would make sense for polls.

JonBob’s picture

Actually UnConeD, it was postponed until after the 4.5 release, not 4.6, and looks like everyone forgot about it when the release happened. And no, Nedjo, I don't take this as proof that Drupal needs more bureaucracy. :-)

Marking this active again; I'm sure the patch will have to be updated once the code branches. We had rolled this function into the needs for CCK, but in our discussions split it off again.

chx’s picture

The patch applies to ucrrent HEAD with some offset. I have rerolled it so it applies cleanly.

chx’s picture

Patch still applies (yes, with some offset, but applies). ANd yes, we need this very badly.

Thox’s picture

I'd benefit greatly from having a feature like this. The example already given is one of the cases I need it: I'd like the title field to be a concatenation of two fields: "First name" and "Last name".

gsperk’s picture

I wonder if someone could help me with the following problem.

After applying the patch I made the output for 'title' in my own_node.module this:

$output .= form_hidden('title', $node->firstname . ' ' . $node->surname);

When the form is first submitted I get the error 'You have to specify a title'. When I submit again the firstname/surname variables are obviously in $node, and the form submits with the desired title.

So, I suppose my question is, how can get the values for firstname and surname into $node without submitting twice? (If it's not obvious I can confirm that I dont have much experience with this kind of stuff. Any suggestions would be a big help.)

Steven’s picture

To make this patch work you also need to move the title validation out of node.module and into the node modules. I don't think this is that much of a problem, it is code that is not going to be touched much.

Also, in light of the upcoming CCK it makes sense to do it like this.

hanoii’s picture

Nice thread.

I have come up with a slightly different approach I think that would need less patching/updating of other modules.

Drupal 4.6.2
node.module:1275

  // Get the node-specific bits.
  // We can't use node_invoke() because $param must be passed by reference.
  $function = node_get_module_name($edit) .'_form';
  $param = array();
  if (function_exists($function)) {
    $form .= $function($edit, $param, $title);
  }

Notice the $title param on the hook_form invoke. This was what I added.

As that hook is called like this an not with the node_invoke() I can define on my custom node module, or patch any module I need to modify the title description with the following hook:

function budget_form(&$node, &$params, &$title) {

and modify the $title argument there, as it is by reference, It will me modified on node.module.

Then again on
node.module:1319

I added/changed the following:

  if ( ! $title ) {
    $title = t('Title') ;
  } 
  $output .= form_textfield($title, 'title', $edit->title, 60, 128, NULL, NULL, TRUE);

So, if the module modify the title var, it uses that, if not, it uses the default one.

Worked for me so far, nice to post on drupal.

Greetings,
a.=

hanoii’s picture

I posted too soon the thing before... :)

I did further patches because of the validation keep telling that I have tu put a "title".

I was happy with the previous patch, not so much with this one, but I let you know what I did...

on the node.module, node_validate() function I move the title validation block just after the


  // Do node-type-specific validation checks.
  node_invoke($node, 'validate');
  node_invoke_nodeapi($node, 'validate');

and added another parameter to the form_set_error()

  // Validate the title field.
  if (isset($node->title)) {
    if (trim($node->title) == '') {
      form_set_error('title', t('You have to specify a title.'), TRUE);
    }
  }

then, on the form_set_error function in common.inc I did the following:

/**
 * File an error against the form element with the specified name.
 */
function form_set_error($name, $message, $checkexistance = FALSE ) {
  if ( !$checkexistance || $checkexistance && !isset($GLOBALS['form'][$name]) ) {
    $GLOBALS['form'][$name] = $message;
    drupal_set_message($message, 'error');
  }
}

So now, if any previous title error was added, and the $checkexistance flag is TRUE, no error will be added to the message queue.

The moving place of the validation block was to let the modules validate first than the node module.

Errrr.. I don't like it, but again, it worked :)

a.=

killes@www.drop.org’s picture

Status: Needs review » Needs work
FileSize
4.56 KB

I've updated the patch to apply to current cvs. As progress on the CCK has been rather slow, I'd appreciate if somebody could address Steven's concerns and the patch could be applied.

Thox’s picture

Status: Needs work » Needs review

Attached is a patch with an attempt to move the title validation code into the node modules (from node.module).

Thox’s picture

FileSize
6.22 KB

attached again (issue preview seems busted?)

nedjo’s picture

Status: Needs review » Reviewed & tested by the community

Thanks chx, killes, and Thox for updates and fixes on the patch.

I've applied and tested it and Thox's changes seem to address the title validation issue.

It's a couple of releases later--it would be great to see this fix applied!

matt westgate’s picture

FileSize
6.04 KB

+1

I've needed to change the name of the title field or even altogether hide it for custom modules.

Issue preview was working for me.

We should document for module developers the implications title-less nodes (e.g., less informative watchdog entries, harder to edit nodes, node title lists become buggy, etc).

I couldn't get the patch to apply cleanly to HEAD so here's a new one.

Robrecht Jacques’s picture

FileSize
6.23 KB

+1 I need this too: I want to be able to set the title of a node automatically.
Patch still applies with offset (rerolled patch attached).

fago’s picture

+1 for this functionality

i've tested the patch and it looks nice, however node_validate_title() produces an validation error, where the field is called title, which isn't suitable if the modules changes the name, as the forum.module does.

Thox’s picture

Perhaps node_validate_title() should be passed the name of the field? 'Title' by default.

fago’s picture

FileSize
7.05 KB

i've updated node_validate_title() as thox suggested and added a title "question" to the poll.module, as there was no title field for it.

fago’s picture

FileSize
7.13 KB

updated the patch again.
now node_validate_title() takes the whole error message as optional second parameter as this allows more customization by modules.

Dries’s picture

Status: Reviewed & tested by the community » Fixed

I'm cool with this patch but don't like node_validate_title(). Can't we simply this function? 3 nested ifs are somewhat hairy. Can we beautify this a little?

killes@www.drop.org’s picture

Status: Fixed » Needs work

fixing status

fago’s picture

FileSize
7.11 KB

you are right.
is it better so?

moshe weitzman’s picture

Status: Needs work » Reviewed & tested by the community

validate function looks sane now.

chx’s picture

This is very important for 4.7 so please...

Dries’s picture

Can we make the $title of node_validate_title non-optional? Also, double-check your spaces.

chx’s picture

FileSize
7.49 KB

I will sit here and give you patches until you commit :)

Dries’s picture

Committed. Please update the documentation, and mark this fixed. Thanks guys!

Dries’s picture

Status: Reviewed & tested by the community » Needs work
remi’s picture

I've added the $edit parameter to the hook_title_field() function, in order to pass the node object in the variable. This way, you can use the data in the node currently being added or edited to be selective on whether the title field should display or not.

Patch is based on 4.6.3 node.module already patched with node.set-title-field_1.patch.

Robrecht Jacques’s picture

remi: the patch that was committed was the one of comment #40. Your patch assumes another incarnation. I think it is no longer needed to pass $edit to any function as the setting of the title and/or title-form is now completely up to the node content type module. The module has full access to the node on the place the form is displayed and/or validated.

moshe weitzman’s picture

Status: Needs work » Fixed

docs are updated - http://drupal.org/node/22218

Anonymous’s picture

Status: Fixed » Closed (fixed)