2

This is all taken from ubercart uc_attribute module.

So in hook_form I have this:

  $items['admin/store/products/attributes/%uc_attribute/edit'] = array(
    'title' => 'Edit attribute',
    'description' => 'Edit a product attribute.',
    'page callback' => 'drupal_get_form',
    'page arguments' => array('uc_attribute_form', 4),
    'access arguments' => array('administer attributes'),
    'file' => 'uc_attribute.admin.inc',
  );

As far as I understand this menu entry will call the function drupal_get_form that will call the function uc_attribute_form using %uc_attribute as a parameter.

Now if I go to the function definition:

function uc_attribute_form($form, &$form_state, $attribute = NULL) {

  // If an attribute specified, add its ID as a hidden value.
  if (!empty($attribute)) {
    $form['aid'] = array('#type' => 'value', '#value' => $attribute->aid);
    drupal_set_title(t('Edit attribute: %name', array('%name' => $attribute->name)), PASS_THROUGH);
  }

It is clear that $attribute is not an integer when it is used by this fucntion. It actually is an attribute stdClass object probably loaded by uc_attribute_load(...).

My question is: What's happening behind drupal_get_form that at the end an integer (the attribute ID) coming from the URL, ends being a full attribute standard object.

I'm kind of learning / developing a module extension and tried to backtrace but definitely couldn't get to an answer.

Thanks!

Juan B.

2 Answers 2

1

Its not related to drupal_get_form, its completely separated events sequentially fired in Drupal.

step 1 - First in menu: argument %something loaded via something_load and passed to page callback as parameters.

step 2 - Second in menu: page arguments will passed to function specified by page callback.

step 3- Third in drupal_get_form: get first argument uc_attribute_form as form ID and use it for build form and get second argument 4 from menu which loaded in step 1. 4 means fifth argument in path 0-admin/1-store/2-products/3-attributes/4-%uc_attribute/5-edit

EDIT: read more about hook_menu

Registered paths may also contain special "auto-loader" wildcard components in the form of '%mymodule_abc', where the '%' part means that this path component is a wildcard, and the 'mymodule_abc' part defines the prefix for a load function, which here would be named mymodule_abc_load().

3
  • Thanks for the answer! So that would mean that in step 1, something_load(%uc_attribute) is called? If that is the case... is that documented somewhere so I can read more about?
    – user11794
    Dec 2, 2012 at 18:53
  • uc_attribute_load is called. something = uc_attribute in this case. post has been edited. Dec 2, 2012 at 19:02
  • Sorry I ddin't realize you posted the same documentation I posted as an answer before posting my answer, lol! Thanks a bunch!!
    – user11794
    Dec 2, 2012 at 19:55
0

Thanks Mohammad but stilldidn't get it very clear. I kept looking in the documentation and I finally found it:

Registered paths may also contain special "auto-loader" wildcard components in the form of '%mymodule_abc', where the '%' part means that this path component is a wildcard, and the 'mymodule_abc' part defines the prefix for a load function, which here would be named mymodule_abc_load(). When a matching path is requested, your load function will receive as its first argument the path component in the position of the wildcard; load functions may also be passed additional arguments (see "load arguments" in the return value section below). For example, your module could register path 'my-module/%mymodule_abc/edit':

  $items['my-module/%mymodule_abc/edit'] = array(
    'page callback' => 'mymodule_abc_edit',
    'page arguments' => array(1),
  );

When path 'my-module/123/edit' is requested, your load function mymodule_abc_load() will be invoked with the argument '123', and should load and return an "abc" object with internal id 123:

  function mymodule_abc_load($abc_id) {
    return db_query("SELECT * FROM {mymodule_abc} WHERE abc_id = :abc_id", array(':abc_id' => $abc_id))->fetchObject();
  }

Thanks anyway for the directions!

Juan

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

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