0

I am using a custom module in my Drupal7 to add data in a form and then inserting it into the database. The form has fields like "Menu Name", "Image", etc. I want to know :

  • How can i show this dynamic content in my site, by clicking on each of the menu items?

    In other words, how to link dynamic content to the menu items? The name of the menu item will be equal to one of the fields (Menu Name) in the form in my custom module. Each of the menu item pages can have a different design & layout (based on form data).

  • Do i need to hack my page.tpl.php?

  • Do i need to create as many .tpl pages as those of menu items for showing the dynamic content?

    I just want to know What is the best way to achieve this.

1

There are 3 broad ways of doing this i) create a widget ii) ajax/json iii) create a block.

The widget method is suitable if you are trying to create an element in the form that is more sophisticated than the form elements provided. You present it in a node--contenttype.tpl.php template. Replace 'contenttype' with the name of the content type you created.

If you want to print out just parts of the data captured in the form then you can use hide($content['fieldname') to get rid of any fields that you don't want rendered. That is the 'streamlined' way. See the 'field example' module in the examples project.

Assuming the module is called ognotify you will need to implement:

  1. ognotify_field_info() to declare the field
  2. ognotify_field_widget_info to define the widget and
  3. ognotify_field_formatter_info() to define the available formats.

These 3 things define the 'edit content type form' in the administration area of drupal.

To process the output you also need to implement

  1. ognotify_field_is_empty($item, $field)
  2. ognotify_field_widget_form(&$form, &$form_state, $field, $instance, $langcode, $items, $delta, $element) to define the form elements

and some validation routines. You can add this 'widget' to any content type.

It sounds as though you are trying to render something more specific. If by dynamic you mean via ajax then one way is to create an ajax block and callback response from the block (module is called bookreview this time).

Define the block as per:

function bookreview_block_display($delta, $args) {
...

This calls a form element of ajax type.

function _bookreview_publish_review_link($args) {
  $block = array();
  if (empty($args['nid']) || empty($args['status'])) {
    return $block;
  }

  $block['content'] = array(
    '#type' => 'link',
    '#title' => 'Publish review',
    '#href' => 'bookreview/publish/' . $args['nid'],
    '#prefix' => '<div class="publish-review" id="ajax-link-div-' . $args['nid'] . '">',
    '#suffix' => '</div>',
    '#ajax' => array(
    'effect' => 'fade',
    ),
 );

 ...
  return $block;
}

Render this on a page. You can do this by mapping blocks, or in code in a template:

$block = module_invoke('bookreview', 'block_display', 'bookreview_publish_review_link', $args);
print render($block['content']

The callback in this example is 'bookreview/publish'. This is the 'access content from a menu' solution. Implement the menu:

function bookreview_menu() {
  $items = array();
  $items[BOOKREVIEW_MODULE_NAME . '/publish/%node'] = array(
    'title' => 'Publish a Book Review',
    'page callback' => 'bookreview_publish_review',
    'page arguments' => array(2),
    'access callback' => 'bookreview_access_callback_check',
    'access arguments' => array(array(BOOKREVIEW_ADMIN_PERMISSION_NAME)),
    'type' => MENU_CALLBACK,
    'file' => 'includes/BookReviewEvents.php',
  );
  return $items;
}

Now we have mapped a menu item (uri) to a function that prints out the content.

function bookreview_publish_review($node) {
  if (!isset($node)) {
    return;
  }

This takes a node argument, %node in the menu definition which automatically gets converted from a node number to a node loaded from the database. The address publish/123 will result in node 123 being passed to your function. You can create a callback for each of the fields in the content type as per /bookreview/menu-name-field/%node. Then create a function to either directly print out the ajax json response:

...
// How you want to get the data from the node. Best to use Netbeans/php debugger
// or dpm() if you don't have it.
$menu_name_field_data = $this->node->{$this->_findMenuFieldName()}[LANGUAGE_NONE][$delta]['value'];
$data_to_print[] = $menu_name_field_data;
ajax_deliver(array('#type' => 'ajax', '#commands' => $data_to_print));
...

The 3rd way is similar to creating the ajax response, except that you define a block that allows you to render the html content. As per the ajax defining a menu item and declaring a block. You print out the content there instead of defining an ajax form.

The widget answer is the most reusable, the ajax answer is the most dynamic and flexible and the block method presents HTML instead of ajax responses. Regarding 'dynamic' the ajax solution best meets your description in the question, although I thought it necessary to present the breadth of the possibilities so that you can make choices regarding the tradeoff between reuse and dynamic.

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.