how to share theme variables with module?
bjillygates - November 7, 2009 - 18:44
Hello,
Have written some module. Want to have access from this module to $variables variable generated for each instance of page.tpl.php. What is the correct way to do this?
Tried to using '$global $variables' declaration in mymodule.module, but it does not work -- no effect. Tried to pass $variables from theme_preprocess(&$variables) function using $_SESSION: part is passed ok, but most important part for me is not passed yet. For example: $variables['primary_links'] became empty on the side of mymodule.module; I tried explicit serialization -- still no effect.
How to solve this issue?
Thanks,

If you are writing a module
If you are writing a module you want to implement modulename_preprocess_page(), see Setting up variables for use in a template (preprocess functions)
Thanks for the reply but it
Thanks for the reply but it does not help at all: what I am doing wrong? I get stuck.
mymodule.module:
<?php
function mymodule_preprocess_page(&$variables)
{
$_GLOBALS['p_links'] = $variables['primary_links']; // primary_links definitely exists -- checked out with 'echo'
}
function somefunc(...)
{
...
drupal_eval(file_get_contents(FILENAME));
...
}
?>
and in FILENAME:
<?phpprint "links =";
print_r($_GLOBALS['p_links']); // shows nothing
?>
I tried out an approach with 'global' keyword -- still the same. Could please anybody point me out what's wrong?
Thanks,
Its not clear what you are
Its not clear what you are trying to do, hook_preprocess_page() is for setting variables used by page.tpl.php. You in fact seem to be replicating the theme system with somefunc().
reversing the theme system
It looks as if you're trying to use the theme system in reverse, but I'm afraid that's not going to work. Drupal calls module hooks first and does the page theming afterwards. I don't know when you're calling somefunc(), but probably, the page theming has not started at that point, so mymodule_preprocess_page() is not yet executed. Also, you can't just run file_get_contents(FILENAME) and expect all variables to be in there - the theme system is much more complicated than that.
You didn't tell us what you're trying to achieve, but in general, there are two options:
1) you're changing the html output or visual appearance of pages, blocks or other elements that already exist (in other words you are "theming")
2) you're creating a new page, block or other element that you want to appear in your site (in other words you're writing a module)
In the first case, you can use preprocess functions like mymodule_preprocess_page and theme overrides. In the second case, you cannot "flash forward" to the page theming. You can however figure out where $variables['primary_links'] gets its contents and do the same in your own code. When you look at http://api.drupal.org/api/function/template_preprocess_page/6, you will see:
$variables['primary_links'] = theme_get_setting('toggle_primary_links') ? menu_primary_links() : array();So in your own module, you could simply use:
<?phpfunction somefunc() {
$p_links = menu_primary_links();
}
?>
2) you're creating a new
Yes, I am creating a module which defines new blocks.
Thanks for the pointer! I have managed to done what I want;
Now it looks like.
mymodule.module:
<?php
// Here I include definition of TemplateData class -- wrapper of $variables
function mymodule_preprocess_page(&$variables)
{
global $theme;
require_once(drupal_get_path('theme', $theme).'/'.'TemplateData.php');
}
// And define the following function
// It will return $variables wrapper to evaluated code in the block which will be defined by the module
function get_template_data()
{
static $tpl = NULL;
if (NULL == $tpl) {
$variables = array();
template_preprocess_page($variables);
$tpl = new TemplateData($variables);
}
return $tpl;
}
?>
Code in the block is evaluated in the way:
<?phpob_start();
require_once('...');
$content = ob_get_contents();
ob_end_clean();
?>
And evaluated code looks like:
<some-html><?php $tpl = get_template_data(); ?>
</some-html>
<again-some-html>
<p>
<b><?php print $tpl->someFunction(); ?> </b>
</p>
</again-some-html>
Thanks for the help!
I'm glad that it works for
I'm glad that it works for you, but it still looks as if you're trying to re-create the theme system. The "Drupal way" to do things like this is to implement hook_theme: see http://drupal.org/node/165706 and http://api.drupal.org/api/function/hook_theme/6 (check out the comments as well).
When you use the Drupal theme system as intended, the following will happen:
0. you have already implemented hook_theme (mymodule_theme()) with a theme hook called "mymodule_block"
1. drupal calls your hook_block implementation (mymodule_block())
2. mymodule_block calls the function the generated the contents for the block (ie. mymodule_block_contents())
3. mymodule_block_contents gets the required data, does the required processing and sends the variables to your theme function or template:
$output = theme('mymodule_block', $variables);4. because you implemented hook_theme, drupal knows to send the $variables to either theme_mymodule_block() or mymodule-block.tpl.php
5. the html output is generated and returned
See also the flowchart (pdf) on http://drupal.org/node/173880, under item 3, to understand more about the theme process and the difference between theme functions and templates.
question is closed. thanks!
Thanks for All for the Help! Question is closed.