Drupal allows you to create "extra fields" through hook_field_extra-fields.

I'd like to be able to load javascript (among other things) in my module, based on the presence of one of these fields, but I can't seem to find a hook that will fire before it renders.

I've tried hook_preprocess_HOOK (for mymodule_preprocess_field), but that didn't work. You can detect for it on hook_preprocess_node, but that doesn't work if the field is being rendered individually, or a in a view. Any ideas?

  • Sorry, I didn't notice that you were saying you'd like to be able to do it when the fields were rendered individually. There's no standard way of rendering a pseudo-field individually AFAIK (you can't field_view_field() it) - they're normally added to an entity. Could you give an example of when it's used individually? (Also could you supply the psuedo-field code or contrib module that provides it?)
    – Andy
    Aug 5 '14 at 12:27
  • @Andy I don't have an example of rendering one individually, but I assumed it could be done (since you can render a single pseudo-field in views using something like drupal.org/project/extrafield_views_integration). If not, then your answer may cover all the use cases.
    – bryanbraun
    Aug 7 '14 at 19:18
  • I'd never seen that project before, thanks. AFAICT it relies on the callback key that isn't part of the core hook_field_extra_fields(). (So basically it's extending core to allow extra fields to be displayed individually.)
    – Andy
    Aug 8 '14 at 9:09
  • Are you dealing with nodes or some other entity?
    – rooby
    Aug 8 '14 at 22:41
  • I'm dealing with nodes.
    – bryanbraun
    Aug 8 '14 at 23:16

It depends on what fields you are dealing with.

hook_field_extra_fields() allows you to define extra fields for any entity, then the field itself is added in a hook that runs when the entity's content is being generated.

That is the place where you need to add the js.

In that hook you can modify the fields you care about and add your js using drupal_add_js() or #attached.

#attached is generally more resilient to caching as it lives with the field render array.

Use #attached like this:

$form['YOURELEMENT']['#attached']['js'][] = drupal_get_path('module', 'MODULENAME') . '/javascript.js';

For example, if the field you want is being added to nodes, you would implement hook_node_view() or hook_node_view_alter() something like this:

function MODULENAME_node_view($node, $view_mode, $langcode) {
  if (isset($node->content['EXTRAFIELD'])) {
    $node->content['EXTRAFIELD']['#attached']['js'] = drupal_get_path('module', 'MODULENAME') . '/javascript.js';

or in hook_node_view_alter() it would be like this:

function MODULENAME_node_view_alter(&$build) {
  if (isset($build['EXTRAFIELD'])) {
    // Change its weight.
    $build['EXTRAFIELD']['#attached']['js'] = drupal_get_path('module', 'MODULENAME') . '/javascript.js';

The same principle can be applied to other entity types, like users, which would use hook_user_view() or hook_user_view_alter().

If your field is on multiple entity types you might have to use multiple of these implementations, or even better, you could use hook_entity_view() or hook_entity_view_alter(), which allow you to target all entity types in the one place.

If you need to make sure your hook runs after all other modules' implementations of that same hook then you can either set the weight of your module higher than others or use hook_module_implements_alter() to make sure your module runs last.

  • I don't think this is the right answer (maybe I'm missing something). hook_field_extra_fields_alter() is not invoked to display a pseudo-field, it simply defines them (and the results are cached).
    – Andy
    Aug 8 '14 at 9:16
  • Oops sorry, you are correct it is the wrong answer. I have fixed the wrong.
    – rooby
    Aug 8 '14 at 22:57

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.