I'm working in a hook menu for a custom route, like this:
function mymodule_menu() {
$items = [];
$items['myroute/%'] = array(
'page callback' => 'my_callback',
'page arguments' => array(1),
'access arguments' => array('access content'),
);
return $items;
}
In the theme_hook, I added a new template feature, like this:
function mymodule_theme($existing, $type, $theme, $path) {
$default = array(
'path' => drupal_get_path('module', 'mymodule') . '/templates',
'variables' => array(),
);
return array(
'product_tile' => array_merge($default, array(
'template' => 'product-tile',
)),
);
}
I created a template file called 'product-tile.tpl.php', which is working fine for all situations and is a partial template.
In the callback function, I need to return a specific .tpl.php template, like this:
function my_callback($parameter) {
$template_data = 'lorem ipsum';
$output = theme('product_tile', array('content' => $template_data ));
echo ($output);
}
The point is: the 'theme()' function is taking too long to render data and it renders not only the template, but the whole html structure, which is not needed and is not part of the template.
Ex: template is:
<div id="my structure></div>
But when i get my response to '/myroute/myparameter, instead of printing my template, it prints all html structure like this:
<html>
<body>......lots of stuff here +js +css + all drupal stuff
<div id="my structure></div>
</body>
</html>
And takes a lot of time to print (like 10s or more).
I tried to cache it by using cache_get and cache_set, but strange things are happening, like random empty responses.
Does anyone know a more performant way to print a partial template in a hook menu in drupal 7? It's terribly slow this way.
Thanks in advance
Your custom route is mapped to a page callback
, a function that must return content to be rendered inside the page to deliver (not just print something).
This content can be either :
MENU_ACCESS_DENIED
, MENU_NOT_FOUND
, etc.)That content (once rendered if not an HTML string) is what you actually get in the $content
or $page['content']
variable being passed to the active theme's page.tpl.php.
Now, your issue may be caused just by using this template (if it contains heavy PHP or bad implementations for example, whatever the reason), but it could be something totally different :
the 'theme()' function is taking too long to render data
The time it takes to deliver that page does not necessarily mean it's caused by this theme function. You can check the time it really takes to render that specific template - not the whole HTML page - it's probably not 10 sec :
$start = microtime(true);
$output = theme('product_tile', array('content' => 'lorem ipsum'));
$end = microtime(true);
$time = $end - $start;
# dpm() is brought by devel module
dpm('product_tile rendering: ' . $time . 'sec.');
The page delivery could be long because of some heavy drupal hooks and preprocess functions involved in rendering your custom template, but it may also be the cost of rendering the other regions of the page (sidebar, header, footer, etc.).
when I get my response to /myroute/myparameter, instead of printing my template, it prints all html :
As explained above, the response for a routed path is a full HTML page that contains as 'content' the output of the 'page callback' defined in the corresponding menu item. The expected behavior for a drupal page callback is precisely to return the content to be displayed on that page, the full HTML page is loaded. That's why a return
statement is expected (don't assume anything if it's not), don't use print
or echo
functions in a page callback, to see what's the content of variables use debugging functions like dpm
) :
function my_callback($parameter) {
$template_data = 'lorem ipsum';
$output = theme('product_tile', array('content' => $template_data ));
# debug the output of 'product_tile'
dpm($output);
# return what should be displayed on that page
return output;
}