Using theme hooks to display a tpl.php on a menu path

The Node, Views and Panels modules can (and should!) handle most pages you need on a site, but sometimes you need complete control of a "hard coded" content area. You could create a new Page node with a Full HTML text format. Instead, how about putting the whole thing in code? Your work will be in version control and much more straightforward to maintain. Imagine editing HTML in a text editor rather than in the Drupal admin! So much better. Additionally, this method allows you to work more easily in a git-based workflow, such as those used by Pantheon or Acquia, without worrying about database changes.

Warnings for the less experienced Drupal site builder: This is specifically written to enforce the theme and logic separation functionality Drupal provides; no logic in the tpl files! If you can make a page in Views, it should be in Views. If you can make it in Panels, it should be in Panels. Do not use this method to recreate the wheel. If you find yourself writing large amounts of SQL queries in the page callback, then you are probably doing something wrong. Do it the "Drupal Way." Your life will be less stressful in the long run. /rant

Ok! Let's get to the code. First thing, make an info file for new module. Be sure to change the "variables" below to match your site and the page/app name.

name = Site Name - Page Name
description = Creates the Page Name for the Site Name
core = 7.x
package = Site Name
version = 7.x-1.0

Then make the module with hook_menu(), a page callback, hook_theme(), and a preprocess function.

 * Implements hook_menu()
function sitename_pagename_menu() {
  $items['page-path'] = array(
    'title' => 'Page Name',
    'type' => MENU_NORMAL_ITEM,
    'page callback' => 'sitename_pagename_page_main',
    'access arguments' => array('access content'),
  return $items;

 * Page callback sets up and returns the content for the Page Name page
function sitename_pagename_page_main() {
  $module_path = drupal_get_path('module', 'sitename_pagename');
  // Add any required jQuery libraries JavaScript. DELETE IF UNNECESSARY!
  drupal_add_js($module_path . '/library.min.js');
  // Add the module path to Drupal.extend. DELETE IF UNNECESSARY!
  $data = array(
    'sitename_pagename' => array(
      'path' => $module_path,
  drupal_add_js($data, 'setting');
  // Add the custom JavaScript. DELETE IF UNNECESSARY!
  drupal_add_js($module_path. '/sitename_pagename.js');
  drupal_add_css($module_path . '/sitename_pagename.css');

  // Render the theme function for this page
  // NOTE: Pass any required variables to theme function using array, see Drupal API.
  return theme('sitename_pagename_main', array('hello' => t('Hello')));

 * Implements hook_theme.
function sitename_pagename_theme() {
  return array(
    'sitename_pagename_main' => array(
      'variables' => array(
        // Specifies both available variables.
        'hello' => NULL,
        'world' => NULL,
      // This allows you to create a tpl file named sitename_pagename_main.tpl.php.
      // It will be automatically loaded by Drupal.
      'template' => 'sitename_pagename_main',

 * Implements hook_preprocess_THEME().
 * This Example preprocesses some variables to pass to the theme function/file.
 * DELETE IF UNNECESSARY! You probably won't need it, but it is here as an example
function sitename_pagename_preprocess_sitename_pagename_main(&$variables) {
  // Use view_embed_view or related here.

  // As an example, this fills in the world variable sitename_pagename_page_main() didn't.
  $variables['world'] = t("World!");

Finally, make the template file.

<strong><?php print $hello;?> <?php print $world;?></strong>

Put the module and code in $DRUPAL_ROOT/sites/all/module/custom/sitename_pagename/. Enable your new module and check the new page at:

Update 7/5/13: New article using this method to implement a template file for a custom block with an admin page to manage it: Instead, how about a Drupal block with a custom settings form?


Thanks man !!

Thanks a lot! Really helped out!

Gracias, información muy buena.
Thanks, information very good.

Error: syntax error, unexpected '(', expecting ')' in

What is the rest of this error message?

good hope, thankyou.

Thanks for this great tutorial.
Wondering, how would one load an existing template within the current theme?
i.e page.tpl.php or page--front.tpl.php

I have a url which passes variables to the front page, which is why I am loading the page again but on a different url.

Thx in advance

I don't understand why you would reload the page to access variables... Can you explain further (if you haven't already solved this issue)