There isn't a limit on the number of lines returned by a page callback, or on the number of tags it can return.
If the output is getting complex, it's rather better to separate the code into different theme functions; for example, for outputting a link there is l(), for outputting an image there is theme('image'), and for outputting a table there is theme('table'). The first rule is to reuse the existing functions.
In Drupal 7, a page callback can also return a renderable array, such as the following one returned by tracker_page():
$page['tracker'] = array(
'#rows' => $rows,
'#header' => array(t('Type'), t('Title'), t('Author'), t('Replies'), t('Last updated')),
'#theme' => 'table',
'#empty' => t('No content available.'),
'#attached' => array(
'css' => array(drupal_get_path('module', 'tracker') . '/tracker.css' => array()),
$page['pager'] = array(
'#theme' => 'pager',
'#quantity' => 25,
'#weight' => 10,
$page['#sorted'] = TRUE;
In these cases, the page callback doesn't return any HTML tags. This is also the preferred method, in Drupal 7, as it allows to the other modules to easily change the output of another module.
As alternative, you can use a template file for rendering the output. In this case, you need to:
Define a theme function that uses the template file; that is what is done from the Node module for theme('node'), which is defined in node_theme() using the following definition (Drupal 7):
'node' => array(
'render element' => 'elements',
'template' => 'node',
Optionally create a preprocess and/or a process function for the template, their purpose is to add variables to the ones that are passed to the template file. In the case of the Node module, those functions are template_preprocess_node() and template_preprocess_node().
Invoke the theme function to produce the output. In the case of
theme('node'), this is done as in the following code:
// Drupal 6.
return theme('node', $node, $teaser, $page);
// Drupal 7.
$build += array(
'#theme' => 'node',
'#node' => $node,
'#view_mode' => $view_mode,
'#language' => $langcode,
This is a common error: The template file name and the theme name must not be different; the only difference can be between using hyphens and using underscores. For the rest, the theme name and the template filename must be the same, which means that "mypage" as theme function and "mynew-page" as template filename don't work; if you are going to use "mynew-page" as template file, then the theme function must be
theme_mynew_page(), reported in the theme definition as "mynew_page."