0

I have a site in Drupal 7 and I have created a custom module for a functionality that I need. Usually, I create custom modules and I create a new page to show them, using the following code:

function my_custom_module_theme() {
    $items = array();
    $items['my_custom_module'] = array(
        'render element' => 'form',
        'path' => drupal_get_path('module', 'my_custom_module') . '/templates',
        'template' => 'my_custom_module-template',
    );
    return $items;
}

function my_custom_module_menu() {
    $items = array();
    $items['my_custom_module'] = array(
        'title' => t('my_custom_module'),
        'page callback' => 'drupal_get_form',
        'page arguments' => array('my_custom_module'),
        'access callback' => TRUE,
    );

    $items['my_custom_module'] = array(
        'title' => t('my_custom_module'),
        'page callback' => 'drupal_get_form',
        'page arguments' => array('my_custom_module_empty_form'),
        'access callback' => TRUE,
    );
    return  $items;
}

function my_custom_module_preprocess_page(&$variables, $hook) {
    $alias = drupal_get_path_alias($_GET['q']);
    if ($alias == "my_custom_module") {
        $variables['theme_hook_suggestions'][] = 'my_custom_module';
        $variables['show_messages'] = TRUE;
    }
}

function my_custom_module_empty_form($form_state) {
    $form = array();
    return $form;
}

and my module appears on mysite/my_custom_module .
What I want to achieve now is to add my custom module at the bottom of an existing node, which has it's own content and functionality.
What should I add to my_custom_module-template.tpl.php or in my node--xx.tpl.php to display my custom module inside the node?
I have already used

<?php
   $nid = xx; // NOTE :: Hard coded, but need to be variable!!
   print drupal_render(node_view(node_load($nid)));
?>   

from a similar Stack overflow question, but it does the opposite of what I want, it renders the node inside the module.

3 Answers 3

4

You can implement hook_node_build() in a custom module to add or alter elements when a node's content is by assembled for viewing, right before rendering.

function MODULE_node_build($node, $view_mode, $langcode) {
  // Only do something if the node is rendered on its own page, in full.
  if ($node->type == 'MODULE_type' && $view_mode == 'full' && node_is_page($node)) {
    $node->content['MODULE_stuff'] = array(
      // Insert render array content here
    );
  }
}

For sorting, you can add a #weight property in the element(s) added to $node->content. But a nicer solution is to implement hook_field_extra_fields(), so you can position the added element(s) using the usual Field UI.

2
  • So, this function is for the .module file . And how should I state the node I wish to render my module? For example, I want node--1.tpl.php . And what happens with the code I posted in my question with hook_menu etc? Should I keep it?
    – Argiris A
    Sep 21, 2016 at 9:35
  • Yes, this should go in the .module file for a custom module. If you want to do something for a specific node, you can check the viewed node's id with $node->nid. The purpose of your hook_menu implementation is to define new routes with page callbacks. If you don't need these routes, you don't need to keep the hook_menu implementation and the page or form builder callbacks. Sep 21, 2016 at 13:56
0

You need to create the functionality in a block. And then display the block wherever you need from /admin/structure/block. To create the functionality use the below code in .module file -

/**
 * Implements hook_block_info().
 */
function MY_MODULE_block_info() {
  $blocks = array();
  $blocks['mycustomform'] = array(
    'info' => t('My custom block'), 
    'cache' => DRUPAL_NO_CACHE,
  );
  return $blocks;
}

/**
 * Implements hook_block_view().
 */
function MY_MODULE_block_view($delta = '') {
  $block = array();

  switch ($delta) {
    case 'mycustomform':
      $block['subject'] = t('Title of the form');
      $block['content'] = drupal_get_form('MY_MODULE_form');
    break;
  }
  return $block;
}

/**
 * Implements hook_form()
 */
function MY_MODULE_form($form, &$form_state) {
  $form['name'] = array(
    '#type' => 'textfield',
    '#title' => t('Name'),
  );

  $form['submit'] = array(
    '#type' => 'submit',
    '#value' => t('Submit Button'),
  );

  return $form;
}

/**
 * Implements hook_form_submit()
 */
function MY_MODULE_form_submit($form, &$form_state) {
    drupal_set_message("You form is successfully submited");
}

Now place it any region of your choice. Say footer of your node.

If you want to control the view from tpl file. Use this code - $block = module_invoke('custom_nodeprocess', 'block_view', 'mycustomform'); print drupal_render($block);

1
  • 1
    A block won't let you add content "inside" a (rendered) node. A block is a high level concept, usually used to allow site administrator to add/remove additional elements (blocks) on the page/ around the main content of the page. In addition, rendering a block from a tpl.php with ` $block = module_invoke('custom_nodeprocess', 'block_view', 'mycustomform'); print drupal_render($block); ` is a terrible practice. Template are supposed to format received data, not fetch and render more data. Sep 20, 2016 at 13:47
0

First it's not clear what you mean by "displaying a module"?!? Module is bunch of code - it can not be "displayed".

Anyway, why complicating thing when you can do it simple? You have your content type and it's template file - node--xx.tpl.php. At bottom of that template file just simply add content that you need. If you have to call some function from your module to generate content dynamically - just do that. It's just question of code organization, but generally you can put any kind of code in your content type's node template, query DB, execute views...do anything you need to acquire data, generate markup out of it and print it directly there, in node template.

Purpose of blocks is allowing admin to dynamically add, remove, re-position content. But if content should always be at the same place having a blocks is overkill. Don't waste code/server resources.

2
  • A template is not supposed to add new data into the page. The role of a template is to format the data it receive, not to fetch more data and format it at the same time. It will "just works", but it's bad practice that lead to unnecessary hard to maintain code. Drupal provides all the API you need to properly add data to a page, especially a node page. If you find a place where you can't add data using an API, you always have templates preprocess function whose purpose is inject/prepare content for formatting in the template. So there is really no reason to o it all in the .tpl.php file. Sep 20, 2016 at 13:43
  • As I mentioned, it's matter of code organization, so he can move logic to module or where ever he want's and just call some function to get the data. Anyway, practice is often different than theory. Sometime you have to do what's easier (faster, productive) then what's dictated by theory.
    – MilanG
    Sep 21, 2016 at 6:11

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.