I have created a custom block and would like to associate it with a tpl in the associated module.
Currently I can associate only a tpl file in the theme folder.
I would like it to be a tpl of the module and then use the hook_menu and pass some data to it, which is impossible (to my knowledge) with a tpl in the theme folder.
Is that even possible?
If this is not possible I would like to use the tpl in my theme as a container and use the hook_menu to pass its contents but I don't know how to return the tpl/theme I will create in the module.
Can someone help me?
I hope the below example helps you
function MYMODULEBLOCK_block_info() {
$blocks['MYMODULE_BLOCK_NAME'] = array(
'info' => t('MYMODULE BLOCK TITLE'),
'cache' => DRUPAL_NO_CACHE, //there are a number of caching options for this
);
return $blocks;
}
function MYMODULEBLOCK_block_view($delta = ''){
switch($delta){
case 'MYMODULE_BLOCK_NAME':
if(user_access('access content')){ //good idea to check user perms here
$block['subject'] = t('MYBLOCK_TITLE');
$block['content'] = MYMODULE_BLOCK_FUNCTION_ITEMS();
return $block;
}
break;
}
}
function MYMODULE_BLOCK_FUNCTION_ITEMS(){
$items = array();
$items['VAR_ONE'] = array('#markup' => 'VAR_ONE_OUTPUT'); //this is the simplest kind of render array
$items['VAR_TWO'] = array(
'#prefix' => '<div>',
'#markup' => 'VAR_TWO_OUTPUT',
'#suffix' => '</div>',
);
// this is where the $items get sent to your default MYMODULE_BLOCK.tpl.php that gets
// registered below
return theme('MYMODULE_BLOCK_FUNCTION_ITEMS', array('items' => $items));
}
//here you are registering your default tpl for the above block
function MYMODULE_theme() {
$module_path = drupal_get_path('module', 'MYMODULE');
$base = array(
'path' => "$module_path/theme",
);
return array(
'MYMODULE_BLOCK_FUNCTION_ITEMS' => $base + array(
'template' => 'MYMODULE_BLOCK', //leave off .tpl.php
'variables' => array('items' => NULL,),
),
);
}
All the stuff in CAPITALS (except DRUPAL_NO_CACHE) can be named whatever you want
And then in a subfolder in your module called theme/ there should be a file called MYMODULE_BLOCK.tpl.php which could have this in it:
<?php
$items = $variables['items'];
print render($items['VAR_ONE']);
print render($items['VAR_TWO']);
And if you wanted to, you could actually overwrite the "default" module implementation you just made for MYMODULE_BLOCK.tpl.php in your theme as you wish in block--MYMODULE--DELTA.tpl.php
The way I do this is as follows...
function YOURMODULE_menu(){
$items['somepage'/%] = array(
'title' => 'Some page title',
'page callback' => 'YOURMODULE_page',
'page arguments' => array(1),
'type' => MENU_CALLBACK,
'access arguments' => array('access content'),
);
return $items;
}
function YOURMODULE_page($data){
$output = 'value from YOURMODULE module! = '.$data;
return theme('theme_file',array('results' => $output));
}
function YOURMODULE_theme() {
$path = drupal_get_path('module', 'YOURMODULE');
return array(
'theme_file' => array(
'variables' => array('results' => null),
'template' => 'theme_file',
'path' => $path,
),
);
}
Place your tpl file theme_file.tpl.php in your module directory and inside it use the below code.
<?php print $results; ?>
or
function YOURMODULE_theme() {
return array(
'theme_file' => array(
'variables' => array('results' => null),
'template' => 'theme_file',
),
);
}
Place your tpl file theme_file.tpl.php in your theme directory and inside it place the below code
<?php print $results; ?>
Go to your http://yourdomain.com/somepage/somedata to see the result.
Related
I have a page.tpl.php in which has header , footer and content area. I need to load different content base on hook_menu from a module.
I am using the following test code in the module to try and print something from my template:
function my_module_theme() {
return array(
'tutorials_test' => array(
'template' => 'tutorial'
)
);
}
I have a template tutorial.tpl.php in the modules folder
The following is my hook_menu and the callback function
function my_module_menu() {
$items['insights/tutorials'] = array(
'title' => 'Tutorials',
'access callback' => TRUE,
'page callback' => 'insights_tutorials'
);
}
The callback function
function insights_tutorials() {
echo 'test';
print theme('tutorials_test');
echo 'after test';
}
When I turn to that page i can see the text 'test' and 'after test' but nothing from my template is printed.
tutorial.tpl.php has this simple code:
<h1>Hello World</h1>
Inside your hook_theme implementation (the function my_module_theme) you need to pass in the variables key
function my_module_theme() {
return array(
'tutorials_test' => array(
'template' => 'tutorial',
'variables' => array( // the variables key
'title' => NULL,
'details' => NULL,
),
)
);
}
Then output your HTML like that:
print theme('tutorials_test', array(
'title' => 'This is the title',
'details' => 'And this is details',
));
For a bitter example about how to implement hook_theme(), take a look at this answer.
Hope this works... Muhammad.
I need to display a page in drupal that is created by a template and based on a specific record from my table.
I created the module "item" (as an example).
I made the item_menu hook:
$items['items/%item'] = array(
'title' => 'Items',
'page callback' => 'drupal_get_form',
'page arguments' => array('show_item', 1),
'access callback' => true,
'access arguments' => array(),
);
I created a load function for the item:
function item_load($itemid)
{
$sql = 'SELECT * FROM {items} it WHERE it.id = :itemid';
$result = db_query(
$sql,
array(':itemid' => $itemid),
array( 'target' => 'mydatabase' ));
$item = $result->fetchObject();
return $item;
}
Now I want to use a template to display the specifics for the item, so I made a item module
a item.tpl.php. and a item_theme hook to register the template:
function item_theme($existing, $type, $theme, $path)
{
return array(
'show_item' => array(
'template' => 'item',
'variables' => array(),
),
);
}
The final thing I need to do is pass the item object to the item.tpl.php so I can display the item properties.
But I don't know how to do this. How can I make the item known within the template??
I hope the question is clear enough. Thanks in advance.
[edit]
I found that arg(1) contains the value of the wildcard from the menu page arguments, should I use arg(1) to look up the item in the database?
You need to declare the names and default values for the vars you want to use in the variables part of your array in hook_theme:
function item_theme($existing, $type, $theme, $path) {
return array(
'show_item' => array(
'template' => 'item',
'variables' => array('var1' => NULL, 'var2' => NULL, 'etc...'),
),
);
}
Then call the theme function like this:
$item_output = theme('show_item', array('var1' => $a_var, 'var2' => $another_var));
** UPDATE **
To address the load() function being called 4 times you can use static vars to avoid the query being run every time:
function item_load($itemid) {
$items = &drupal_static(__FUNCTION__, array());
if (!isset($items[$itemid])) {
$sql = 'SELECT * FROM {items} it WHERE it.id = :itemid';
$items[$itemid] = db_query(
$sql,
array(':itemid' => $itemid),
array('target' => 'mydatabase')
)->fetchObject();
}
return $items[$itemid];
}
Let's say I have this implementation of hook_menu():
function example_menu(){
$items = array();
$items['admin/recent-completions'] = array(
'title' => 'Recent Completions (Last 100)',
'page callback' => 'example_recent',
'access callback' => user_access('Administer content'),
'type' => MENU_NORMAL_ITEM,
'weight' => -50
);
return $items;
}
How can I make a template for the page callback instead of returning a string?
You would need to implement a hook_theme function and specify a template file.
Then in your page callback, you would have to call your theme function. Something like...
function example_theme($existing, $type, $theme, $path) {
return array(
'recent_completion' => array(
'render element' => 'elements',
'template' => 'recent-completions',
),
...
}
function example_recent() {
// Do some logic and processing here
$render_array = array( /* array with parameters for the template */ );
return theme('recent_completion', $render_array);
}
I had the same question, but wasn't sure how to implement a hook_theme function. This is how it's done (in Drupal 6 at least).
I have created a module for Drupal 7 which has a hook_theme function that tells it to use usertemp.tpl.php template. I have the template placed in the module folder as well as the theme folder. The problem is that the function is ONLY picking up the template from the module folder but not from the theme folder. I have cleared the caches repeatedly and looked for previous answers but nothing helps. What could be the problem?
My code for the hook_theme looks like this:
function usuar_theme() {
return array(
'usuarbuild' => array(
'variables' => array('profilesloaded' => array()),
'template' => 'usertemp',
),
);
}
The rest of the module code is this:
function usuar_menu() {
$items['userx'] = array(
'title' => 'User page',
'description' => 'User page',
'page callback' => 'usuar_exe',
'access callback' => TRUE,
'type' => MENU_CALLBACK,
);
return $items;
}
function usuar_exe($id) {
$ar = array('uid' => $id, 'profilesloaded' => profile2_load_by_user($id));
return theme('usuarbuild', array('collected' => $ar));
}
function theme_usuarbuild($variables) {
return $variables['collected'];
}
This is a tricky one, but.. your theme hook must match your template name. Weird, but I tested this on my local and it worked once I set it up that way. So.. change your hook_theme() to:
function usuar_theme() {
return array(
'usuarbuild' => array(
'variables' => array('profilesloaded' => array()),
'template' => 'usuarbuild',
),
);
}
And change your tpl.php file to usuarbuild.tpl.php (or change everything to usertemp). Should work after that.
I am trying to build my own module in Drupal 7.
So I have created a simple module called 'moon'
function moon_menu() {
$items = array();
$items['moon'] = array(
'title' => '',
'description' => t('Detalle de un Programa'),
'page callback' => 'moon_page',
'access arguments' => array('access content'),
'type' => MENU_CALLBACK
);
return $items;
}
function moon_page(){
$id = 3;
$content = 'aa';
}
in moon_page() function, I like to load a custom template 'moon.tpl.php' from my theme file.
is this possible?
/*
* Implementation of hook_theme().
*/
function moon_theme($existing, $type, $theme, $path){
return array(
'moon' => array(
'variables' => array('content' => NULL),
'file' => 'moon', // place you file in 'theme' folder of you module folder
'path' => drupal_get_path('module', 'moon') .'/theme'
)
);
}
function moon_page(){
// some code to generate $content variable
return theme('moon', $content); // use $content variable in moon.tpl.php template
}
For your own stuff (not overriding a template from another module)?
Sure, you only need to:
Register your template with hook_theme()
Call theme('moon', $args)
$args is an array that contains the arguments to the template as specified by your hook_theme() implementation.
For Drupal 7, it did not worked for me. I replaced line in hook_theme
'file' => 'moon', by 'template' => 'moon'
and now it is working for me.
In drupal 7 I was getting the following error when using :
return theme('moon', $content);
Was resulting in "Fatal error: Unsupported operand types in drupal_install\includes\theme.inc on line 1071"
This was fixed using :
theme('moon', array('content' => $content));
You may use moon_menu, with hook_theme
<?php
/**
* Implementation of hook_menu().
*/
function os_menu() {
$items['vars'] = array(
'title' => 'desc information',
'page callback' => '_moon_page',
'access callback' => TRUE,
'type' => MENU_NORMAL_ITEM,
);
return $items;
}
function _moon_page() {
$fields = [];
$fields['vars'] = 'var';
return theme('os', compact('fields'));
}
/**
* Implementation of hook_theme().
*/
function os_theme() {
$module_path = drupal_get_path('module', 'os');
return array(
'os' => array(
'template' => 'os',
'arguments' => 'fields',
'path' => $module_path . '/templates',
),
);
}