Set PHP Variables for Drupal 7 Theme Files - drupal

I want to set custom php variables that can be used throughout my drupal theme (html.tpl.php, page.tpl.php etc.) I need the variables set based on the $title of the node. I'm not an expert on how Drupal works, the moduling and hooks, and I just need to know the simplest/easiest way to accomplish this. I keep reading about implementing some sort of hook in the template.php file where you can set variables, but I've been unsuccesful with everything I've tried.
So, basically, how would you accomplish this:
Get $title of Node
Set variables that will be passed along into theme files (for example, to do basic things like: if($title == 'news_page') { $siteSection = "news"; } )
Have $siteSection be available to use in theme files
Any help would be great.. thanks!

Before Drupal builds the HTML for a page from a theme's template (.tpl.php file), it runs preprocess "hooks". Hooks are basically a naming convention for functions that let modules and themes override or "hook" onto Drupal core processes.
E.g., if you want to display a message to a user when they log in, you can use hook_user_login.
function MODULENAME_user_login(&$edit, $account) {
drupal_set_message("Welcome, ". $account->name);
}
When a user logs in, Drupal looks for all loaded functions that end in "_user_login" and it runs them. If this function is in an enabled module, it has been loaded, so it will get run as well.
If you want to make a variable named $site_section available in your page.tpl.php file, you can hook into template_preprocess_page. This is a theme hook, so the name is a little different, but it functions pretty much the same way. To call this hook from your theme, you need to create a file called template.php in your theme's directory. Inside template.php, we'll add:
<?php
function THEMENAME_preprocess_page(&$vars){
switch (drupal_strtolower($vars['node']->title)) {
case "about page":
$site_section = "about";
break;
case "news page":
case "news page1":
case "news page2":
$site_section = "news";
break;
default:
$site_section = "none";
break;
}
$vars['site_section'] = $site_section;
}
The <?php is used to tell the server the treat all of the proceeding code as PHP. We then declare our hook function with the intention of loading Drupal's array of page variables into a local variable called $vars. By adding the & before $vars, we'll be allowed to modify the values for use outside of this function.
The switch statement will let us efficiently test the page title for multiple values. The value of the node's title may contain uppercase letters, lowercase letters, and symbols, so to avoid a case-sensitive mismatch, we're going to convert the title to lowercase and only test that (symbols will still be in the title, though). After the switch statement, we set the value of our $site_section local value into the referenced $vars array for use in page.tpl.php.
However, if it's just your intention to break the site up into sections for theming purposes, there are other ways of accomplishing that. My answer to a similar situation a few months ago might be helpful.

Related

WordPress constant scope using define method

I'm defining plugin path as a constant through constant define method as shown below.
define( 'MY_PLUGIN_DIR', untrailingslashit( plugin_dir_path( __FILE__ ) ) );
It is accessible within plugin all files and themes. But when I call this constant in another plugin this constant becomes undefined.
How I can get this plugin constant in another plugin? Any help will be appreciated.
Thanks,
Probably your problem is the order that wordpress is calling your plugins: the plugins that sets the constant is loaded after the one who calls it.
A better explanation of how to force your plugin be loaded first can be found here. I'm putting here a quote of the part that matters:
The order that plugins are loaded (as of WP 2.9.1 at least) is determined by the order of an array stored as "active_plugins" in the WP options table. Whenever a plugin is activated, it is added to this array, the array is sorted alphabetically by plugin name, and the array is saved to the DB.
Fortunately, there is a convenient action hook, "activated_plugins", that is called after the active plugins array is saved to the DB. This allows you to manipulate the order of the plugins stored in this array after the array is initially saved.
You'll have to the following PHP code in the plugin who defines the constant, then deactivate and reactivate it (copied from the link I providaded above).
function this_plugin_first() {
// ensure path to this file is via main wp plugin path
$wp_path_to_this_file = preg_replace('/(.*)plugins\/(.*)$/', WP_PLUGIN_DIR."/$2", __FILE__);
$this_plugin = plugin_basename(trim($wp_path_to_this_file));
$active_plugins = get_option('active_plugins');
$this_plugin_key = array_search($this_plugin, $active_plugins);
if ($this_plugin_key) { // if it's 0 it's the first plugin already, no need to continue
array_splice($active_plugins, $this_plugin_key, 1);
array_unshift($active_plugins, $this_plugin);
update_option('active_plugins', $active_plugins);
}
}
add_action("activated_plugin", "this_plugin_first");
Hope it helps!

Drupal 6 preprocess function for custom template

I have a custom template file I'm using for a page.
Say the page is www.mydomain.com/hello-world
The content of this page is taken from a template file called hello-world.tpl.php
Now I need to have a variable prepared in advance for that page, so I took a look at how core modules achieve this and tried to implement in the same way, only the variables are always null..
for hello-world.tpl.php I created in my module file a function called:
function template_preprocess_hello_world(&$variables) {
$variables['test'] = "test";
}
As I said $test doesn't get any value on www.mydomain.com/hello-world (I receive NULL when var dumping it)
I spent an hour or so double checking that I don't have any typos or anything like that.
Is what I'm doing worng??
Try renaming the function to mymodulename_preprocess_hello_world(&$variables). Don't forget to clear the cache as well.

How do you use a view with arguments as the site front page in Drupal?

I have a Drupal site and I have setup a view to power the front page.
My goal is to be able to pass 0-2 arguments to the home page, that get passed into the view. However, I still need the normal Drupal pages to work. The list of arguments is known.
For example:
mysite.com/berlin/birds would pass in "berlin" as the first argument and "birds" as the second argument to the view that powers the front page.
mysite.com/berlin would just pass in one argument, "berlin"
mysite.com/admin would load the normal admin pages in Drupal
I'm not clear on how to achieve this. Is there a hook I can use? I can't find one or think of one. Is there a way to specify this in the argument for the view itself? Perhaps I can write a hook that interjects when the URL is being loaded, and rewrite in the background?
The solution I currently have is to add these paths (since my arguments are known) to the menu system. This works, except that when I the pages they aren't the front page, so the pages don't use the node themes I want (they use the node details theme).
I don't think you can really do this without custom code. The View needs a path before it starts taking arguments, and your URLs start with the arguments. What you can do is fake it with custom code. I've used something like this:
/**
* Implements hook_init().
*/
function mymodule_custom_init() {
$item = menu_get_item(); // Matching Drupal path
if (!$item) { // There is no matching Drupal path.
$_GET['q'] = 'view_path/' . $_GET['q']; // Fake path path.
} // if
} // mymodule_custom_init
Then you give the view a path of "view_path" and it responds to everything that doesn't match anything else in Drupal's paths.
There is a spot in the views UI for "Argument handling code" that takes a small snippet of php - http://drupal.org/node/70145
You could run some code there that checks to see if you are on the front page (or arguments are not present or whatever)and insert the arguments you want.
Another way is to set arguments via a hook_views_pre_view or hook_views_pre_build. Is better because you are sure you don't break other stuff (like another view block).
function MYMODULE_views_pre_view(&$view){
if ($view->name == 'your_view_name' && drupal_is_front_page()) {
$view->set_arguments(array('you_argument','you_second_argument'));
}
}

How do I dynamically change ubercart's default messages from my module

There are some products for which I would like to have a special checkout complete message that would differ from the default.
I know that I could probably do this by changing the default redirect page to something else. [And I'm not sure if that would introduce another problem]
However, I would like to know if there is a standard/better way of approaching this problem.
Thanks!,
D
Consider the String Overrides module. Here is a quote about it (from the module's project page):
Provides a quick and easy way to replace any text on the site.
Features:
Easily replace anything that's passed through t()
Locale support, allowing you to override strings in any language
Ability to import/export *.po files, for easy migration from the Locale module
Note that this is not a replacement to Locale as having thousands of overrides can cause more pain then benefit. Use this only if you need a few easy text changes.
I guess the only other possible way of doing what I am thinking of is to override the theme function that ubercart uses to display the message. And this probably seems like it would make the most sense.
In this case I would override theme_uc_cart_complete_sale
I could set a
$_SESSION['is_special_product'] == TRUE;
and then set $message to my $special_message if it's been set.
if ($_SESSION['special_product']) {
$special_message = t('This is my special message');
$message = variable_get('special_product_message', $special_message;
}
Finally, to override from my module I will need to hook into the pre-process hook:
function $modulename_prepocess_$hook(&$message) {
if ($_SESSION['special_product']) {
$special_message = t('This is my special message');
$message = variable_get('special_product_message', $special_message;
}
}
It is important to note that it is not enough to have this function in your module. The preprocess functions are only invoked when the template file that overrides the theme function is called.
More details can be found at http://drupal.org/node/223430

Drupal - Getting node id from view to customise link in block

How can I build a block in Drupal which is able to show the node ID of the view page the block is currently sitting on?
I'm using views to build a large chunk of my site, but I need to be able to make "intelligent" blocks in PHP mode which will have dynamic content depending on what the view is displaying.
How can I find the $nid which a view is currently displaying?
Here is a more-robust way of getting the node ID:
<?php
// Check that the current URL is for a specific node:
if(arg(0) == 'node' && is_numeric(arg(1))) {
return arg(1); // Return the NID
}
else { // Whatever it is we're looking at, it's not a node
return NULL; // Return an invalid NID
}
?>
This method works even if you have a custom path for your node with the path and/or pathauto modules.
Just for reference, if you don't turn on the path module, the default URLs that Drupal generates are called "system paths" in the documentation. If you do turn on the path module, you are able to set custom paths which are called "aliases" in the documentation.
Since I always have the path module turned on, one thing that confused me at first was whether it was ever possible for the arg function to return part of an alias rather than part of system path.
As it turns out, the arg function will always return a system path because the arg function is based on $_GET['q']... After a bit of research it seems that $_GET['q'] will always return a system path.
If you want to get the path from the actual page request, you need to use $_REQUEST['q']. If the path module is enabled, $_REQUEST['q'] may return either an alias or a system path.
For a solution, especially one that involves a view argument in the midst of a path like department/%/list, see the blog post Node ID as View Argument from SEO-friendly URL Path.
In the end this snippet did the job - it just stripped the clean URL and reported back the very last argument.
<?php
$refer= $_SERVER ['REQUEST_URI'];
$nid = explode("/", $refer);
$nid = $nid[3];
?>
Given the comment reply, the above was probably reduced to this, using the Drupal arg() function to get a part of the request path:
<?php
$nid = arg(3);
?>
You should considder the panels module. It is a very big module and requires some work before you really can tap into it's potential. So take that into considderation.
You can use it to setup a page containing several views/blocks that can be placed in different regions. It uses a concept called context which can be anything related to what you are viewing. You can use that context to determine which node is being viewed and not only change blocks but also layout. It is also a bit more clean since you can move the PHP code away from admin interface.
On a side note, it's also written by the views author.
There are a couple of ways to go about this:
You can make your blocks with Views and pass the nid in through an argument.
You can manually pass in the nid by accessing the $view object using the code below. It's an array at $view->result. Each row in the view is an object in that array, and the nid is in that object for each one. So you could run a foreach on that and get all of the nid of all rows in the view pretty easily.
The first option is a lot easier, so if that suits your needs I would go with that.
New about Drupal 7: The correct way to get the node id is using the function menu_get_object();
Example:
$node = menu_get_object();
$contentType = node_type_get_name($node);
Drupal 8 has another method. Check this out:
arg() is deprecated

Resources