I need to use the Nodereference URL Widget with Profile2 profiles. Guess what? They aren't nodes. Instead I'm going to use Rules Link.

I used Rules Link instead for Nodereference URL Widget on a job listing content type that needs a button for a user to add a job application to. So I created a Rules Link instance and set the visibility on the entity type, bundle and user role access. The Rule also contains a single action to redirect the user to node/add/application?field_reference_job_listing=[node:nid]. The return path can be included with adding &destination=[node:url:path].

This field needs to be rewritten to emulate the varies fallback behaviors of the Nodereference URL widget. I went with page not found.

Now the form needs to be intercepted and the field's default value needs to be set. This is easier programtically using the Nodereference URL Widget which provides a of useful variables in the form variable to user. However, since the Entity References module is being used it is a bit more tricky. I use hook_field_widget_FIELD_ID_form_alter and it looks something like this.

function MODULE_field_widget_entityreference_autocomplete_form_alter (&$element, &$form_state, $context){
  
  if ($context['field']['field_name'] == 'field_reference_job_listing'){

    extract($context);
    
    $handler = entityreference_get_handler($field);

    // We let the Field API handles multiple values for us, only take
    // care of the one matching our delta.
    if (isset($items[$delta])) {
      $items = array($items[$delta]);
    }
    elseif (isset($_GET['field_reference_job_listing']) && is_numeric($_GET['field_reference_job_listing'])) {
      $items = array(
        array(
          'target_id' => $_GET['field_reference_job_listing'],
        ),
      );
    }  
    else {
      drupal_set_message(t('To create an application, first go to the job listing page of the job you would like to apply to and click the apply button.'));
      drupal_not_found();
      exit();
    }
    
    $entity_ids = array();
    $entity_labels = array();

    // Build an array of entities ID.
    foreach ($items as $item) {
      $entity_ids[] = $item['target_id'];
    }

    // Load those entities and loop through them to extract their labels.
    $entities = entity_load($field['settings']['target_type'], $entity_ids);

    foreach ($entities as $entity_id => $entity) {
      $label = $handler->getLabel($entity);
      $key = "$label ($entity_id)";
      // Labels containing commas or quotes must be wrapped in quotes.
      if (strpos($key, ',') !== FALSE || strpos($key, '"') !== FALSE) {
        $key = '"' . str_replace('"', '""', $key) . '"';
      }
      $entity_labels[] = $key;
    }

    $element['target_id']['#default_value'] = implode(', ', $entity_labels);
    $element['target_id']['#default_label'] = $label;
    $element['target_id']['#default_id'] = $entity_id;
    $element['target_id']['#access'] = FALSE;
  }
      
  return $element;
}

function MODULE_form_application_node_form_alter (&$form, &$form_state, $form_id) {
  $lang = $form['field_reference_job_listing']['#language'];
  if ($label = $form['field_reference_job_listing'][$lang][0]['target_id']['#default_label']){
    $form['company_name'] = array(
     '#markup' => '<label>Submit an application to ' . $label . '</label>',
     '#weight' => 0,
    );
  }
}

Comments

mitchell’s picture

Title: A short tutorial on how to use Rules Link *without* Nodereference URL Widget » How to use Rules Link to populate Entity References
Component: Miscellaneous » Documentation
Status: Active » Needs review

This is a great start! Let's try and work this into a documentation page.

I'm a bit concerned about recommending custom code, but I really like lean solutions. So, if we could get more user input and review this code as well some related projects, then maybe we can come up with an easily reusable solution. Here's what I found so far:

http://drupal.org/project/prepopulate
http://drupal.org/project/entityreference_prepopulate
http://drupal.org/project/url_operations
http://drupal.org/project/rules_url_argument

Or perhaps another module that allows the default field value setting to configured to use url parameters. I did this before with a page link that directed user to a node/add page with an additional parameter that a custom php code parsed and filled in the field. I've also seen other similar methods based on the referrer too.