Hi,
I just want to post some stuff that we did at our site for customizing biblio. It's nothing that should go into the module because it handles some very special needs. If someone else ever wants to do sth. similar, this might help. You need yo deploy your own module to do all of this (note that everything below uses the bio_ prefix because we are a Chair for Bioinformatics and our module and theme is named "bio" ;-)). So this is only interesting for people who are interested in hacking into drupal and making every little piece exactly as they want it :-)

Customizing the input form:
We want to have three kind of input elements for every biblio type: required elements, optional but visible elements, optional invisible elements (i.e. hidden in a fieldset). This can be done with biblio, but we wanted that all other fields, that we never needed, should not show up anywhere! So the "Other Biblio fields" fieldset should only contain fields that are defined for a certain type.

We did that via hook_form as follows (example for the book type): First disable *all* fields for the book type, i.e., none is required, non is visible. Then put this in yours module hook_form:

  $bio_required_fields = array();
  $bio_optional_fields = array();
  $bio_hidden_fields = array();
  switch ($form['biblio_type']['#options'][$bibtype]) {
  case "Book":
    $bio_required_fields = 
      array ('biblio_year',
                 'biblio_contributors_wrapper',
                 'biblio_publisher');

    $bio_optional_fields = array ('biblio_edition',biblio_isbn');
    $bio_hidden_fields   = 
      array ('biblio_volume',
                 'biblio_secondary_title', // Series
                 'biblio_place_published', // Address
                 'biblio_date',
                 'biblio_notes',);
    break;

Now we put the required and optional fields into the edit form:

  // IMPORTANT: we expect all the fields are marked as 'invisible'
  // (and none as required) so that they are in the "Other biblio fields"  fieldset.  

  // Order fields in the order they are set in the arrays above
  $weight = 50;

  // Make required fields required :-)
  foreach ($bio_required_fields as $field) {
    $form['bio_biblio_fields'][$field] = $form['other_fields'][$field];
    $form['bio_biblio_fields'][$field]['#required'] = TRUE;
    $form['bio_biblio_fields'][$field]['#weight'] = $weight;
    $weight++;
  }

  // Get optional fields. Always include DOI and citekey.
  $bio_optional_fields[] = 'biblio_doi';
  $bio_optional_fields[] = 'biblio_citekey';
  foreach ($bio_optional_fields as $field) {
    $form['bio_biblio_fields'][$field] = $form['other_fields'][$field];
    $form['bio_biblio_fields'][$field]['#weight'] = $weight;
    $weight++;
  }

The hidden fields go into a fieldset so that they must be uncollapsed to be viewed, just the normal "Other Biblio fields" fieldset:

  if (!empty($bio_hidden_fields)) {
    $form['bio_hidden_fields'] = array(
      '#type' => 'fieldset',
      '#collapsible' => TRUE,
      '#collapsed' => TRUE,
      '#title' => t('Additional Biblio fields'),
      '#description' => '',
      '#weight' => 500,
      );
    foreach ($bio_hidden_fields as $field) {
      $form['bio_hidden_fields'][$field] = $form['other_fields'][$field];
      $form['bio_hidden_fields'][$field]['#weight'] = $weight;
      $weight++;
    }
  }

And finally we hide the "Full Text" and "Other Biblio fields" stuff:

  unset($form['body_field']);
  unset($form['other_fields']);

This way you have only the fields that you want for your type and can still hide some not so often used, while not getting a list of dozens of unneeded options when uncollapsing the "Other Biblio fields" set.

Note that we wouldn't need the additional ['bio_biblio_fields'] array level above, we just use that for the next feature but you can go without.

Restyling the tabular view:
We use the tabular view when someone clicks at a publications title, but we wanted some special stuff there, like a special order of the fields, hide some export links (there might be a config option for this soon) or removing the "Publication language" field.

You need to use hook_theme to redefine the theming function like

    'biblio_tabular' => array(
      'function' => 'bio_theme_biblio_tabular',
      'arguments' => array(
        'node',
        'base' => 'biblio',
        'teaser' => FALSE
        ),
      ),

But the question is how you handle the bio_theme_biblio_tabular function. You can copy all the code from biblio_theme.inc and change it, but it contains a lot of code for DB access etc. and is likely to fail whenever Ron changes sth. at the biblio tables.

So there is an easier way to get what you need, i.e., the names of the fields defined for the type and their data: The input form!


function bio_theme_biblio_tabular($node, $base = 'biblio', $teaser = false) {
  // drupal_retrieve_form will use node_form, so make it known
  require_once(drupal_get_path('module', 'node') ."/node.pages.inc");

  $args = array();
  $form = drupal_retrieve_form('biblio_node_form', $args, $node);
  drupal_prepare_form('biblio_node_form', $form, $args);
  drupal_process_form('biblio_node_form', $form, $args);

Now you have all fields for your record available in $form and you can go through all options like:

  $rows[] = bio_biblio_tabular_row('Publication Type', $node->biblio_type_name);

  foreach (array('biblio_year', biblio_secondary_title', 'biblio_publisher', ...) as $field) {
  if (!empty(field['#default_value'])) {
    $rows[] = bio_biblio_tabular_row($field['#title'], $field['#default_value']);
  }
 ...
}

Here bio_biblio_tabular_row is just a little helper function like

function bio_biblio_tabular_row($title, $value) {
  return array(
    array(
      'data' => '<span class="biblio-row-title">'. $title .'</span>',
      'align' => 'right',
      ),
    array(
      'data' => '&nbsp;&nbsp;',
      ),
    array(
      'data' => $value,
      ),
    );
}

And that's it and you can define the ordering of the fields, the look of the table, whatever.

Btw., if you restyled the edit form like above, then you easily build a table for all defined fields with

  foreach($form['bio_biblio_fields'] as $field) {
    if (!empty($field['#default_value'])) {
      $rows[] = bio_biblio_tabular_row($field['#title'], $field['#default_value']);
    }
  }

  foreach($form['bio_hidden_fields'] as $field) {
    if (is_array($field) && !empty($field['#default_value'])) {
      $rows[] = bio_biblio_tabular_row($field['#title'], $field['#default_value']);
    }
  }

At the end you need a return theme('table', array(), $rows); or whatever you want for theming.

Maybe this gives peopls who want to hack some biblio features some ideas how to do it. have fun :-)

Comments

mariagwyn’s picture

Is it possible to attach the actual files you created? I am a little confused as to where some of these pieces go. Is this a custom module, or is this a .tpl file? It looks like bits of both to me.

thanks!
m

Frank Steiner’s picture

This is all in a custom module, no tpl needed. I can't post the module here because it contains a lot of other stuff for our site which is partly interweaved with the code stuff for biblio. That's why I posted the snippets regarding biblio here. There is no file I can give you to just download and install and then it works. If you know how to setup your own custom module and what hook_theme and hook_form is, and have looked into the biblio theming machanism, then the snippets above should help you, otherwise not, I'm afraid.

mariagwyn’s picture

thanks, I can figure it out now that I know it is in a custom module.

gpiersol’s picture

Thank you Frank for posting this. I'd love to apply your code to simplify the biblio input pages.

I'm new to writing modules and form modifications and I am getting an error:

Parse error: syntax error, unexpected T_CONSTANT_ENCAPSED_STRING, expecting ')'... that corresponds with the line beginning
array ('biblio_volume',

I suspect I'm doing something wrong but I opened my module (after <?php) with
function mymodule_form_alter($form_id, &$form) { mymodule_required_fields = array(); etc.

Even though I'm finding a lot of instructions related to hook_form and hook_theme, I'm having problems figuring out how to apply those instructions in this particular situation.

Thanks,
Geoff

Frank Steiner’s picture

Well, this is just a syntax problem somewherein your code. Like you forgot the "=" in the line before etc. It's a pure php problem, nothing todo with form_alter or sth.

gpiersol’s picture

Thanks for your reply.

I found and corrected the syntax error (a missing apostrophe) and the custom module is now generating no errors. It also seems to be having no effect on the biblio book type node/add page and I'm assuming its related to the function in my custom module:

function bibcustom_form_alter(&$form, $form_state, $form_id) {

$bibcustom_required_fields = array();
$bibcustom_optional_fields = array();
$bibcustom_hidden_fields = array();
switch ($form['biblio_type']['#options'][$bibtype]) {
case "Book":

etc...

I'm still struggling with using custom modules to edit forms, so any pointers would be greatly appreciated.

Next question: If I don't need to follow the second stage of the above code for theming the the table view, I'm not sure how to end off the custom module function for the Book case, after the

 unset($form['body_field']);
  unset($form['other_fields']);

- Is it something like return $form;?

Thanks again

bekasu’s picture

Assigned: Unassigned » bekasu
Status: Active » Closed (fixed)

Marking this issue closed. If you want to pursue further HowTo information, please begin a discussion in the forums rather than in the Biblio issue queue.

thanks,
bekasu