Drupal 7 gotchas / bugs

Notes about Drupal 7 gotchas / bugs.

Index

Theming blocks inside panels

If you add a block to a panel(https://www.drupal.org/project/panels){:.weblink} then you won’t be able to use theme it using the normal template_preprocess_block() function (or templates presumably) unless you change its style to ‘System block’ (via its settings when editing the panel content).

You could alternatively use the panels preprocess functions template_preprocess_panels_pane() but this doesn’t seem to give you much to play with.

Cron.php 404 not found

If you’re on shared hosting and you find that wget http://example.com/cron.php returns a 404 not found, it could be because cron.php is group writable. You should get a 403 forbidden (unless you provide the correct cron key parameter, in which case it should be found).

To fix, deny the group write permission:

chmod g-w cron.php

Can’t use dpm() in templates

The dpm() function won’t work in theme templates or template functions.

Use kpr() instead.

Date field rounding when editing

I had an unlimited Date field on an entity bundle, which stored its date values correctly in the database but rounded to the nearest 5 minutes when editing the entity. The dates showed correctly when viewing the entity.

Turned out this was due to a bug with the Date module’s Text Field widget, which unlike the pop-up calendar widget does not allow you to choose an increment and defaults to a value larger it should.

The bug report is here: date field minutes and seconds rounding after update/save

As a work-around, until the bug is fixed, use the pop-up calendar widget instead of the text widget.

Temporary managed files and the private filesystem

If you try and upload a file destined for the private filesystem, but you haven’t set your private filesystem path via admin/config/media/file-system, you may get the following error:

Warning: is_dir() [function.is-dir]: Unable to find the wrapper “private” - did you forget to enable it when you configured PHP? in file_prepare_directory() (line 437 of /home/test/drupal7/includes/file.inc).

The file will not have been uploaded (because the private filesystem path wasn’t set) but Drupal may have added a temporary entry to the file_managed table, depending on how the module you were using was implemented. Temporary entries will have a URI beginning with temporary://. They will be cleared up automatically via cron. Alternatively you can delete it manually from the file_managed table.

If you try and upload the same file again before its temporary entry is removed from the file_managed table, then you may get the following error:

Recoverable fatal error: Object of class stdClass could not be converted to string in DatabaseStatementBase->execute() (line 2171 of /home/test/drupal7/includes/database/database.inc).

Rules OR condition format

When using an OR conditional in a rule, each condition should be a child of the conditional. So x OR y OR z should be specified as follows:

  • OR
    • x
    • y
    • z

References

Set form #action so they still work when cached

If you are defining a form that will appear on multiple different pages (which it most likely will knowing Drupal) then you must set its #action parameter:

/**
 * Implements hook_form().
 *
 * @param array $form
 * @param array $form_state
 * @param string $form_id
 * @return array Form config.
 */
function my_form($form, &$form_state) {
  ...
  $form['#action'] = '#';
  ...
}

If you don’t do this then the form’s action parameter will be cached as the URL of the page on which the form is first rendered, causing it to always submit to that page regardless of which other pages it is shown on.

Can’t set border on radio buttons

If you’d like to set a border on radio buttons when there’s an error, you need to use the outline property:

.form-item input.form-radio.error {
  outline: 1px solid red;
}

Note that I’ve targetted input.form-radio.error rather than just input.error because use of override will prevent you overriding border on the other elements.

No paragraphs with Filtered HTML format

Despite the help text of the ‘Filtered HTML’ text format informing you that that “Lines and paragraphs break automatically”, they don’t. Line breaks and paragraphs will be filtered out because they aren’t listed in the allowed HTML tags.

To add them, go to Configuration -> Text formats -> Configure (Filtered HTML) -> ‘Limit allowed HTML tags’ section and add <p> and <br/> to the list of allowed tags.

‘Main page content’ block ordering

Drupal 7 comes with a block called ‘Main page content’ in the Content region. You may find that the ordering of this block is ignored by Drupal when you add other blocks to the region. To fix, simply change the position the ‘Main page content’ block within the region, save, then change it back - for some reason it takes this reshuffling for Drupal to update the weight of the block.

Content type missing from ‘add content’ page

Is the Node Limit module restricting the available types?

Don’t mix and match field arrays

At least in Views.

This works:

    foreach($variables['fields'] as $id => $field) {
      $field->wrapper_prefix = '';
      $field->label_html = '';
      $field->wrapper_suffix = '';
    }

This doesn’t (it will generate errors, though oddly still render the fields):

    foreach($view->field as $id => $field) {
      $field->wrapper_prefix = '';
      $field->label_html = '';
      $field->wrapper_suffix = '';
      $variables['fields'][$id] = $field;
    }

Taxonomy term menu callback called a too many times

Given the following code…

function [mymodule]_menu_alter(&$items) {
  if (isset($items['taxonomy/term/%taxonomy_term'])) {
    $items['taxonomy/term/%taxonomy_term']['access callback'] = '[mymodule]_access_check';
    $items['taxonomy/term/%taxonomy_term']['access arguments'] = array(2);
  }
}

function [mymodule]_access_check($term) {
  ...
}

… The [mymodule]_access_check function will be called loads of times. I counted 19 times on a taxonomy term page that showed only 4 nodes.

Yes/No checkbox

It is not possible to have a checkbox return ‘No’ when unchecked - it can only return 0. You can change it to return ‘Yes’ when checked, by using the ‘#return_value’ setting, e.g:

  $form['communications'] = array(
    '#title' => t('Further communications'),
    '#description' => t("Check the box if you'd like to receive communications from Some Company."),
    '#type' => 'checkbox',
    '#default_value' => 'No',
    '#return_value' => 'Yes',
    '#required' => FALSE
  );

Note: default value can be anything other than ‘Yes’ to have the checkbox unchecked by default.

Email Sender header doesn’t match the From address

drupal_mail() doesn’t change the Sender header when you change the From address (though it does when it defaults to use the site email). This can cause problems in some email clients. Instead, you can do this from your hook_mail() implementation:

$message['headers']['Sender'] = $message['headers']['Return-Path'] = $message['headers']['From'];

Theming taxonomy term pages

taxonomy-term.tpl.php is only responsible for outputting the term’s fields, not the nodes categorised by that term. The nodes are themed via node.tpl.php.

You can use preprocess functions to e.g. check for a particular vocabulary in order to theme the templates differently. E.g:

[mytheme]_preprocess_node(&$variables, $hook) {
...
  // Determine whether we're viewing the 'Agents' vocab (ID 4).
  $variables['viewing_agents_vocab'] = FALSE;
  if (arg(0) == 'taxonomy') {
    $term = taxonomy_term_load(arg(2)); 
    if ($term->vid == 4) {
      $variables['viewing_agents_vocab'] = TRUE;
    }
  }
...
}

function [mytheme]_preprocess_taxonomy_term(&$variables, $hook) {
  // Determine whether we're viewing the 'Agents' vocab (ID 4).
  $variables['viewing_agents_vocab'] = FALSE;
  $term = $variables['term'];
  if ($term->vid == 4) {
    $variables['viewing_agents_vocab'] = TRUE;
  }
} 

The $viewing_agents_vocab variable will now be available in both taxonomy-term.tpl.php and node.tpl.php, which allows you to conditionally theme depending on whether you’re viewing the ‘Agents’ vocab or not.

A blank template override will be ignored

If you override a template it must return some content (even if it’s a space character) otherwise it will be ignored and the next template up the hierarchy will be used instead.

For example, you override taxonomy-term.tpl.php in your theme:

<?php if ($term->vid == 4): ?>
  .. some content ..
<?php endif; ?>

If $term-vid == 4 it won’t output any markup and will be ignored by Drupal, so the term page will still render as the parent template will be used instead.

If you add this to the end it’ll work fine because it’ll output markup regardless of the condition:

<?php print ' '; ?>

View name must not contain hyphen

Views should not allow you to create a view with a hyphen in its name, but as of 20/04/2011 it does. This will break Panels when trying to add a view pane. See Call to undefined method get_argument_input().

Get stylesheet

drupal_add_css() returns the stylesheet array. drupal_get_css() returns their rendered HTML links.

Module caching

When developing modules, you will need to clear the site cache to register any new methods added to yourmodule.module file.

You can hide particular node links by removing them before render:

<?php unset($content['links']['comment']['#links']['comment-add']); ?>

Alternatively, in the page template, you can hide all node links but not specific links and you have to target a specific part of the render array.

This works:

<?php hide($page['content']['system_main']['nodes']['1']['links']['node']); ?>

These don’t work:

<?php hide($page['content']['system_main']['nodes']['1']['links']); ?>
<?php hide($page['content']['system_main']['nodes']['1']['links']['node']['#links']['node-readmore']); ?>
<?php hide($page['content']['system_main']['nodes']['1']['links']['node']['#links']); ?>

Theme functions vs preprocessors

Theme functions, e.g. theme_form, are responsible for generating markup, while preprocess functions e.g. theme_preprocess_html are responsible for setting up variables used in a template.

Usability

Main menu shows in default theme but main menu block is not set to display anywhere.

Images

This is probably due to my server setup. Some directories in sites/X/files only get 700 permission, e.g. files/fields and files/styles/large medium thumbnail, resulting in broken images.

Stylesheet / css loading

You can not use a theme’s .info file to load multiple stylesheets with the same basename. E.g. the following won’t work:

stylesheets[handheld][] = f3-yaml/css/screen/anti.css
stylesheets[only screen and (max-device-width: 480px)][] = f3-yaml/css/screen/anti.css

Only the second anti.css will be used.

See Stylesheet override logic prevents loading of stylesheets of third-party libraries.

The work-around is to use drupal_add_css function, supplying it a basename.

path_to_theme()

The path_to_theme() function will return the sub-theme’s path when it’s used in code that’s “inherited” by the sub-theme. Use drupal_get_path instead:

drupal_get_path('theme','the_theme_name')

See function path_to_theme.

Sub theme inheritance

See Creating a sub-theme.

A sub theme does not inherit regions, screenshot and logo from parent theme, so these have to be defined in its .info file.

You can override templates and theme functions (i.e. the sub-theme’s templates/functions are used over its parents), but preprocess functions are inherited (i.e. the parent’s preprocess functions are run before the sub-theme’s ones).

Remember: Theme functions, e.g. theme_form, are responsible for generating markup, while preprocess functions e.g. theme_preprocess_html are responsible for setting up variables used in a template.

Comments in [theme].info

In the [theme].info file, comments must be on their own line. E.g. If you have a comment after a variable assignment, the comment will be part of the assignment:

    settings['f3_setting'] = 'Value' ; Comment
    ...
    theme_get_setting['f3_setting'] -> 'Value ; Comment'

Display of excluded fields in Views

If you exclude a field from display, its content will still show up if used as the format’s grouping field. This can actually be used to create nested grouping, whereby you aggregate the content of many excluded fields into the (rewritten) output of another excluded field that’s used as the format’s grouping field.

Field vs view naming (Views 3)

Field name includes field_ prefix, view name doesn’t have a prefix: field_[field_name] vs view_name.

Search page vs block

The search page has a form with a “Enter your keywords” label and options for an advanced search (when permissions allow). The search block form has neither.

Filtering views by taxonomy vocabulary

You can filter a view by multiple vocabularies, by using the taxonomy term ID filter. If you expose the filter, there’s no problem - the user can select the term - but if you don’t expose the filter you won’t immediately be able to select the term - you’ll see “Taxonmy: Term (or Unknown)” on saving the filter.

In order to select the term, you have to first save the view, then edit the filter to select the term, because the view won’t know which terms are availble until you save it.

Form state does not show when form is submitted

Bug.

function [mymodule]_form($form, &$form_state) {
  ...

  // This is always set and always empty.
  $form_state['submitted']

  ...
}

‘Undefined index’ errors

Drupal 7 has apparently turned PHP error reporting to E_ALL, so that notices are shown (I believe by default PHP won’t show notices). This can result in ‘undefined index’ errors. For example, the contact module of Drupal 7.17 will generate the following when you attempt to use it at an anoymous user (I also got it with admin) because it checks for a ‘copy’ field that wasn’t added to the form:

> Notice: Undefined index: copy in contact_site_form_submit() (line 155 of /var/www/html/modules/contact/contact.pages.inc).

See my bug report here: Undefined index: copy in contact_site_form_submit().

A temporary solution is to turn off PHP notices, by adding the following line to sites/default/settings.php:

/**
 * Ignore PHP notice errors - Drupal 7 now shows them by default, but even core
 * modules generate them (e.g. contact.pages.inc line 155 with anonymous user)
 */
ini_set('error_reporting', 'E_ALL ^ E_NOTICE');

“Notice: Undefined index” quick fix in drupal7 error reporting

Last modified: 13/12/2015 Tags: ,

This website is a personal resource. Nothing here is guaranteed correct or complete, so use at your own risk and try not to delete the Internet. -Stephan

Site Info

Privacy policy

Go to top