Define entity in module and edit existing items I am trying to create a module which defines an entity (called "didyouknow") with two fields: ID and content.

I have set it up to create new items of this custom entity, but I can't get it to work for editing existing items.

I'm trying to reuse the same form (didyouknow_item_form()) for creating and editing, which works fine for creating, but for editing. The "%didyouknow" part in the URL is supposed to mean that the argument of didyouknow_item_edit() is a loaded entity object, but it isn't; if I output it within that function using print_r(), it outputs as "structure." This results in PHP outputting:


  Notice: Trying to get property of non-object in didyouknow_item_form()


The code for the functions is below:

function didyouknow_menu() {
    $items['admin/structure/didyouknow/manage/add'] = array(
    'title' =&gt; 'Add Did You Know item',
    'page callback' =&gt; 'didyouknow_add',
    'access arguments' =&gt; array('create didyouknow'),
  );
  $items['admin/structure/didyouknow/manage/%didyouknow/edit'] = array(
    'page callback' =&gt; 'didyouknow_item_edit',
    'access arguments' =&gt; array('create didyouknow'),
    'page arguments' =&gt; array(1),
  );
  return $items;
}

function didyouknow_item_edit($didyouknow){
  return drupal_get_form('didyouknow_item_form', $didyouknow);
}

function didyouknow_add() {
    $didyouknow = (object) array (
    'pid' =&gt; '',
    'type' =&gt; 'didyouknow',
    'content' =&gt; '',
  );

  return drupal_get_form('didyouknow_item_form', $didyouknow);
}

function didyouknow_item_form($form, &amp;$form_state, $didyouknow) {
  $form['content'] = array(
    '#type' =&gt; 'textarea',
    '#title' =&gt; t('Content'),
    '#default_value' =&gt; $didyouknow-&gt;content,
    '#required' =&gt; TRUE,
  );

  $form['submit'] = array(
    '#type' =&gt; 'submit',
    '#value' =&gt; t('Save'),
  );

  field_attach_form('didyouknow', $didyouknow, $form, $form_state);

  return $form;
}

function didyouknow_item_form_validate($form, &amp;$form_state) {
  $didyouknow_submission = (object) $form_state['values'];
  field_attach_form_validate('diyouknow', $didyouknow_submission, $form, $form_state);
}

function didyouknow_item_form_submit($form, &amp;$form_state) {
  $didyouknow_submission = (object) $form_state['values'];
  field_attach_submit('didyouknow', $didyouknow_submission, $form, $form_state);
  $didyouknow = didyouknow_item_save($didyouknow_submission);
  $form_state['redirect'] = "admin/structure/didyouknow/manage/$didyouknow-&gt;pid/edit";
}

function didyouknow_item_save(&amp;$didyouknow) {
  return entity_get_controller('didyouknow')-&gt;save($didyouknow);
}
You have two problems in that code. First of all, you assume that having a didyouknow-id in the URL, is enough for Drupal to know where to get your object, the second problem is that your page argument is off.

This simplified code:

$items['admin/structure/didyouknow/manage/%didyouknow/edit'] = array(
  // …
  'page arguments' =&gt; array(1),
);


will pass on "structure" as an argument, not the %didyouknow id, nor a didyouknow-object, which is why you get an error about a "non-object". Argument indexing start with 0 => admin, so (as already mentioned by LToomre) you need to have:

'page arguments' =&gt; array(4),


It is also important to note that Drupal will not automatically know how to load your entity, you are required to provide the load function yourself.

As an example, look at the epay module, which has a menu hook like this:

$items['payment/epay/callback/%epay_hash'] = array();


The named argument %epay_hash, is automatically mapped to a _load function:

function epay_hash_load($hash) {}


which takes the URL argument as parameter, performs the DB queries necessary to load your object, and then returns it.