How can I modify or pre-process the <body> tag to add the class body? I don't want to create a whole html.tpl.php just to add a class.
In your theme's template.php file use the preprocess_html hook:
function mytheme_preprocess_html(&$vars) {
$vars['classes_array'][] = 'new-class';
}
Remember to clear the caches once you've implemented the hook or Drupal won't pick it up.
The documentation for the html.tpl.php template documents the $classes variables as String of classes that can be used to style contextually through CSS.. If you look at the code for the template, this variable is used in the class attributes of the produced body element:
<body class="<?php print $classes; ?>" <?php print $attributes;?>>
The $classes variables is actually already set by template_process() for any template file and build from the content of the $classes_array variable.
So to add a class to the body of your page, you should add this class to the $classes_array value from your theme (or module)'s implementation of hook_preprocess_html():
function THEME_preprocess_html(&$variables) {
$variables['classes_array'][] = 'new-class';
}
Since this is the core defined template and process function, any well-behaving theme should re-use the same variables.
I had to use different array keys in the same hook to make it work:
function THEME_preprocess_html(&$vars) {
$vars['attributes_array']['class'][] = 'foo2';
}
The Context module allows you to add a class to the body tag as well.
This can be useful if you need the class to be added under certain conditions.
You find this options under the reaction "Theme HTML" :
The answer appears to depend on context. Here's what I've found via trial-and-error:
If your hook_preprocess_html() is in a module, use $vars['classes_array'][].
If it's in a theme, use $vars['attributes_array']['class'][].
Common Body Class module provide users to add classes to any page through the an interface.
The interface has options to select multiple user roles as well as pages where the class can be rendered.
I applied this technique on a site that someone else built. It didn't work at first but then dug deeper and found that the $classes variable was not being output in the tpl file. So if it's not working, check that.
For Drupal 7 install http://drupal.org/project/body_class. It will help you to add seperate classes for each node in body tag
You can check "https://www.drupal.org/project/page_specific_class" to add class to body tag of any page
It's a simple way to add a class based on the URL, Drupal 9.
No need to enable the Modules.
/**
* Implements hook_preprocess_html().
*/
function THEME_NAME_preprocess_html(&$variables) {
// Get the current path
$current_path = \Drupal::service('path.current')->getPath();
$internal_path = \Drupal::service('path_alias.manager')->getAliasByPath($current_path);
// Assign it to body class
$variables['attributes']['class'][] = str_replace("/", "", $internal_path);
}
Refer: http://www.thirstysix.com/how-can-i-add-body-class-based-path-page-specific-class-drupal-9
Related
I wanted to add for block it custom type class in twig layout file: block.html.twig
But i have no idea how to get type.
Class is just needed for styling needs, cause i have many blocks in multiple languages. I don't want to style elements by their custom ids.
Actually i found one working solution, which one uses Theme hook:
/**
* Implements hook_preprocess_HOOK() for block.html.twig.
*/
function MYTHEME_preprocess_block(&$variables) {
// adding custom attribute class for block
if ($variables['elements']['#base_plugin_id'] == 'block_content') {
$blockType = strtr($variables['content']['#block_content']->bundle(), '_', '-');
$variables['attributes']['class'][] = 'block--type-' . $blockType;
}
}
This one is adding class for custom block types only. But works for my needs.
I could add extra functionality to a dataobject if I extend it with a dataextension. For example I've got an Item which gets extended from a module with stock keeping functionality. Let's say the Item also gets's extended form a few other modules.
After the extension with the stock keeping functionality, I'd like to display the availability of the item in the frontend, for example with a green/red dot. How can I get this dot's markup inside my template for the detail page(ItemPage.ss) and the include (Item.ss) for the overview page of items without overwriting the whole template. Just adding this one part, like the way I extend a function on my base class?
That could be a way to add extra markup to the original template.
Inside dataobject or global dataobject extension
public function ExtraTemplateHTML($position) {
$html = null;
foreach($this->owner->extend('updateExtraTemplateHTML') as $positionBlocks) {
if(isset($positionBlocks[$position])) {
foreach($positionBlocks[$position] as $htmlBlock) {
$html .= $htmlBlock->getValue();
}
}
}
return $html;
}
Inside the specific dataobject extension
public function updateExtraTemplateHTML($htmlBlocks) {
$viewer = new SSViewer(__CLASS__);
$html = $viewer->process($this->owner);
$htmlBlocks['bottom'][] = $html;
$topHtml = HTMLText::create();
$topHtml->setValue(123);
$htmlBlocks['top'][] = $topHtml;
return $htmlBlocks;
}
Original Template
$ExtraTemplateHTML(top)
...
...
$ExtraTemplateHTML(bottom)
Extension Template
Than just write a new template for your extension with the content you would like to add.
You cannot partially change a template, you can only substitute the template with another. So, keeping this in mind you should keep modular architecture with many logical includes.
Another possible way to extend existing content is using DOM and javascript. But you should think about side effects. For example if you add extra textual content then it won't be visible by crawlers and will effect your SEO. But for decorative enhancements, like adding extra coloured dot, this approach will work.
I'm currently coding a WP plugin and would need to override templates.
My filter hook looks like that - and it executes:
add_filter('template_include', 'mcd_set_template',10);
function mcd_set_template() just returns the required path as string - or the default WP template in case the file not exists.
I'm toying with this for hours already, even could include that alternate template (but it appears at the bottom of the page).
So my question is, how to force WP 3.2.1 to just load another template file instead - and which priority is required??
Update:
Also I noticed when using var_dump ... it outputs almost at the end of the file - but should appear before the opening HTML tag...
According to this ticket it should work with template_include hook: http://core.trac.wordpress.org/ticket/11242
Or is the only way to hook these filters instead:
http://codex.wordpress.org/Template_Hierarchy#Filter_Hierarchy
?
You could use template_redirect as shown above, but that does require exit, and it does trample on everything else WordPress would normally do to find the current template. You may want to let that happen and then apply logic to the current template.
Using some of what is above...
add_action('template_include', 'mcd_set_template');
function mcd_set_template() {
return locate_template('templatename.php');
}
That is fairly simple, you can also pass an array to locate_template() to define a hierarchy. If you were to use 'template_redirect as shown above, you should still be using locate_template, and this is how.
add_action('template_redirect', 'mcd_set_template');
function mcd_set_template() {
/**
* Order of templates in this array reflect their hierarchy.
* You'll want to have fallbacks like index.php in case yours is not found.
*/
$templates = array('templatename.php', 'othertemplate.php', 'index.php');
/**
* The first param will be prefixed to '_template' to create a filter
* The second will be passed to locate_template and loaded.
*/
include( get_query_template('mcd', $templates) );
exit;
}
Finally, the best way would be to filter specific types instead of the whole hierarchy. For example you could filter 'category_template' or 'page_template'. That would be more specific, it would avoid messing with the whole template hierarchy if you don't want to - and it lets WordPress do more of the heavy lifting
For example:
add_filter('category_template', 'filter_category_template');
function filter_category_template($template){
/* Get current category */
$category = get_queried_object();
/* Create hierarchical list of desired templates */
$templates = array (
'category.php',
'custom-category-template.php',
'category-{$category->slug}.php',
'category-{$category->term_id}.php',
'index.php'
);
return locate_template($templates);
}
You can of course create that array of hierarchical templates any time you use locate_template(). Using this method, its easy to see how easily you could create all sorts of very detailed and specific hierarchies either as part of or separate from the native Template Hierarchy.
Have you tried using an add_action instead? For example, you might want to try something like the following in your plugin:
add_action('template_redirect', 'mcd_set_template');
//Redirect to a preferred template.
function mcd_set_template() {
$template_path = TEMPLATEPATH . '/' . "templatename.php";
if(file_exists($template_path)){
include($template_path);
exit;
}
}
Here is a helpful reference: http://www.mihaivalentin.com/wordpress-tutorial-load-the-template-you-want-with-template_redirect/
I am working on a module where i have a page that must have no regions or extra content. A kind of "please wait" page.
How do i diable all extra content (regions menus...etc) ? i think Panels has this ability but i can't find the snippet it uses.
On another hand is it possible for a module to specify a special custom page ? like the maintenance-page for example ?
The page.tpl.php method is not flexible. It is based on a presentation logic. You should use hook_page_alter() for a business logic solution. For example:
function yourmodulename_page_alter(&$page) {
if (current_path() == 'node/add/yourcontenttype') {
unset($page['sidebar_first']);
}
}
Also look at very powefull Context module.
You can create a an extra page.tpl.php specifically for the page where you want to hide the regions. The naming principle is similar to the one for nodes.
Let's say you have a page with the url example.com/content/contact. A template named page--content--contact.tpl.php would serve that page and any page that starts with that url, i.e. the page example.com/content/contact/staff would also use that template (I think).
Check the classes of the body element for clues to what you can name your template, most themes will print that. In my example above, the body element would include the class page-content-contact.
Only thing i can think of is writing checks in your page.tpl.php file to see if you on that "page" your talking about and not printing out the regions/menus, or use a different template. http://drupal.org/node/223440
If you want to do this before the blocks are rendered:
/**
* Implements hook_block_list_alter()
*
* Hides the right sidebar on some pages.
*/
function THEME_NAME_block_list_alter(&$blocks) {
// This condition could be more interesting.
if (current_path() !== 'node/add/yourcontenttype') {
return;
}
// Go through all blocks, and hide those in the 'sidebar_second' region.
foreach ($blocks as $i => $block) {
if ('sidebar_second' === $block->region) {
// Hide this block.
unset($blocks[$i]);
}
}
}
Note: Interestingly, this hook seems to work no matter if you have it in your theme or in a module.
(Please correct me if I'm wrong)
How can I create a custom page.tpl.php for a specific view?
I'm not talking about styling the view itself, just the page where that view gets rendered.
Thank you.
#Keith Morgan - It's page.
Per Allartk's solution
In Drupal 7 template.php:
function <theme>_preprocess_page(&$variables) {
if (($views_page = views_get_page_view()) && $views_page->name === "galleries") {
$variables['theme_hook_suggestions'][] = 'page__views__galleries';
}
}
Then in your theme directory, create the page--views--galleries.tpl.php file.
Clear drupal cache and template should work.
I used 'galleries' as and example views name.
You can create a template file to theme almost any aspect of views output. In your case you want to create a custom template for your page display.
On the view designer, click the Theme link in Basic Settings. You'll see some template file naming options depending on if you want to theme the whole view (e.g., views-view--example--page.tpl.php), each row (e.g., views-view-fields--example--page.tpl.php) and so on.
Copy the appropriate template you want to customize from /sites/all/modules/views/theme to your theme and customize as you wish.
Once you create your custom template file, you can go back to the view designer Theme link to make sure it is being used. Your template should be bolded.
Hope this helps.
There's some documentation on template suggestions, and you might be interested in page.tpl.php suggestions. If it's a page view, you could use a path suggestion. So if your view is at http://www.example.com/photos, the page.tpl.php file would be named page-photos.tpl.php.
Had a similar problem, which was remedied by putting a .tpl.php in my theme's template folder. The naming convention for a page display of views in drupal 7 is page--path-to-view.tpl.php
In a drupal 7 theme I added a template suggestion in template.php:
function sovon_preprocess_page(&$variables) {
if(views_get_page_view()) {
$variables['theme_hook_suggestions'][] = 'page__view';
}
}
See http://api.drupalize.me/api/drupal/function/views_get_page_view/7 and http://drupal.org/node/223440#custom-suggestions for more information.
Assuming a view as a page, you can use the results of page_manager_get_current_page() in your preprocess to determine if your view is active, then take the appropriate steps (tack on body classes, add a template suggestion, etc).
using sillygwailo's suggestion I got this to work for me very nicely:
function YOUR-THEME-NAME_preprocess_page(&$vars) {
//allow template suggestions based on url paths.
$alias = drupal_get_path_alias(str_replace('/edit','',$_GET['q']));
if ($alias != $_GET['q']) { $suggestions = array();
$template_filename = 'page';
foreach (explode('/', $alias) as $path_part) {
$template_filename = $template_filename . '-' . $path_part;
$suggestions[] = $template_filename;
}
$alias_array = explode('/', $alias);
$variables['template_files'] = $suggestions;
Then if your view is at www.example.com/photos , create a page-photos.tpl.php in your theme directory and drupal will use that as your template.
If that checked answer doesnt work(because it didnt for me) you can create a page--(urlname).tpl.php and then style your theme however you want it. Then you can import your view in one of several ways ...
print render($page['content']);
or
$view = views_get_view('viewname');
print $view->execute_display('default', $args);
$args is just an array and can be blank..you can just leave it off entirely