how do I call my theme preprocess function for a specific field? - drupal

i'm on Drupal 7 and i have aspecific tpl.php file for a content field_image: "field--field_image.tpl.php". I need to create a preprocess function for this field and for my theme.
Supposing my theme name is "My Theme"
It should look like
function my_theme_preprocess_field(&$variables, $hook) {
$variables['classes_array'][] = 'aClassName';
}
but it doesn't work. I am wrong. But where?
Thanks

You can use template_preprocess_field() (like you do in your code above) but just test the particular field is the right one for you:
function my_theme_preprocess_field(&$variables, $hook) {
$element = $variables['element'];
if (isset($element['#field_name'])) {
if ($element['#field_name'] == 'field_image') {
$variables['classes_array'][] = 'aClassName';
}
}
}
Once you've implemented the hook don't forget to clear your caches, hook implementations are cached in Drupal 7 so won't be picked up until the cache is cleared.

You could declare a mytheme_preprocess_field(&$variables, $hook) in your theme's template.php where you can check your field and do operations on its label or markup, add classes, anything. So you wouldn't need field specific tpls. - eg.
function mytheme_preprocess_field(&$variables, $hook) {
if ($variables['element']['#field_name'] == 'field_machine_name') {
$variables['items'][0]['#markup'] = 'add custom markup';
}
}
Hope this helps someone.

In drupal 7 you can rewrite output of the field in template_preprocess_node() by altering "#markup" value of the field.
Also you can use regexp to change whatever you want in page content :)

Related

How I can print all variable of a hook in drupal 8?

I'm very new in Drupal 8 and I have issue now with hook. Mainly I though that I don't clearly understand structure and hook definition in Drupal 8.
So my main problem is that I have some hook to interact with main menu (add custom class name to ul, li and link, a tag). I can do it by changing template file and now try to do it with any hook.
Although I found that some hook relating to menu ex. hook_contextual_links_alter (link: https://api.drupal.org/api/drupal/core%21lib%21Drupal%21Core%21Menu%21menu.api.php/function/hook_contextual_links_alter/8.9.x).
At the end of this hook we have the code related:
function hook_contextual_links_alter(array &$links, $group, array $route_parameters) {
if ($group == 'menu') {
// Dynamically use the menu name for the title of the menu_edit contextual
// link.
$menu = \Drupal::entityTypeManager()
->getStorage('menu')
->load($route_parameters['menu']);
$links['menu_edit']['title'] = t('Edit menu: #label', [
'#label' => $menu
->label(),
]);
}
}
So I have installed devel module with kint function and in my .theme file and try:
function hook_contextual_links_alter(array &$links, $group, array $route_parameters) {
kint($links);
}
and then reload my Home page but nothing showed. But I can get some information about other like:
function eg_learn_theme_suggestions_page_alter(&$suggestions, $variables) {
kint($suggestions);
}
So what happens here? Can you help to explain if how I can print the variable of this hook (in .theme file) and the site page to see the printing variable?
In general when I found a hook, how I can print there array and check it in website?
There are some problems about your approach:
When implementing a hook, you must replace "hook" with the module name/theme name where you put the hook function inside. For example, if you want implement hook_contextual_links_alter in your_custom module, it becomes your_custom_contextual_links_alter().
Not all hook can be implemented in the theme. Some hook can only be implemented in modules (in .module file). You can read more here.
In your case, I think hook_preprocess_menu would be more suitable. You can implement it in your custom theme like this:
function <your_theme_name>_preprocess_menu(&$variables) {
if ($variables['menu_name'] == 'main') {
kint($variables);
}
}

How can I customize a specific node in Drupal 6 WHEN a custom template has already been applied to the node's content type?

[For Drupal 6] Let's say I've created a content type called "my_content_type". I can override the default template for that entire content-type by creating "page-node-my_content_type.tpl.php". But, what would be the best way to then further customize a single node of that content type (e.g., node 5555)?
I tried the following, but none worked:
page-node-5555.tpl.php
page-node-my_content_theme-5555.tpl.php
node-5555.tpl.php
None of these work. They all continue to use my original content-type template.
Drupal's page templates work on a suggestion system. Based on the current URL, an array of possible template files is created. It loops through the array (in reverse order) looking for template files that exists. The first one it finds, it will use.
drupal's theme system provides a hook for you to modify the template suggestions.. open up your template.php and find
function phptemplate_preprocess_page(&$vars) {
the $vars variable is what contains the suggestions, specifically $vars['template_files']
By default the only page suggestions that are available are
page.tpl.php
page-node.tpl.php
page-node-[node_id].tpl.php
As far as im aware, page-node-[node_type].tpl.php does not work by default, so its likely you have already modified the preprocess_page template to added in this functionality.
However if you want to add more specific templates you could do something like this...
function phptemplate_preprocess_page(&$variables) {
if ($variables['node']->type != "") {
$variables['template_files'][] = "page-node-" . $variables['node']->type;
$variables['template_files'][] = "page-node-" . $variables['node']->type . "-" . $variables['node']->nid;
}
}
this will allow the following hierarchy of template suggestions
page.tpl.php
page-node.tpl.php
page-node-[node_id].tpl.php
page-node-[node_type].tpl.php
page-node-[node_type]-[node_id].tpl.php
In Drupal 7 just copy the page.tpl.php template and rename it as
page--node--[node:id].tpl.php
Clear cache and start tweaking..
function phptemplate_preprocess_page(&$variables) {
if ($variables['node']->type != "") {
$variables['template_files'][] = "page-node-" . $variables['node']->type;
$variables['template_files'][] = "page-node-" . $variables['node']->type . "-" . $variables['node']->nid;
}
}
This code should not work because hook_preprocess_page() does not get passed any node information. hook_preprocess_node() does. So you can easily create a custom node.tpl, but you cannot easily create a custom page.tpl for a specific node. Not that I've been able to figure out anyway :)
Later...
In default Drupal, page-node-NID.tpl.php will work with no special coding. On a site of mine, it wasn't working, however, and I used the following code to make it work:
/**
* Implementation of hook_preprocess_page().
*/
function MYMODULE_preprocess_page(&$variables) {
// Allow per-node theming of page.tpl
if (arg(0) == 'node' && is_numeric(arg(1))) {
$variables['template_files'][] = "page-node-" . arg(1);
}
}

Get $node variable in html.tpl.php - Drupal 7

I'm trying to allow users to update head titles and meta descriptions for each page. I thought that an easy way to achieve this would be to add a field to the 'Basic page' content type for the page title, then check if that field is not empty in html.tpl.php and if it is not, override $head_title with this user-defined value.
However, it appears that the $node variable is not available in html.tpl.php. Can anyone suggest a way for me to make this data available in this template file, or alternatively, alter $head_title before it is sent to html.tpl.php? Thanks for reading.
Taken in part from this thread that I found: http://drupal.org/node/1041768...
In your template.php, you can do the following:
function yourtheme_preprocess_html(&$variables) {
// If on an individual node page, add the node type to body classes.
if ($node = menu_get_object()) {
$variables['head_title'] = $node-> // find your cck field here
}
}
Bit messy, but would work:
if(arg(0) == 'node' && !empty(arg(1))) {
$node = node_load(arg(1));
}
However, you might prefer http://drupal.org/project/metatags_quick (an interrim module until the full http://drupal.org/project/metatags is finished).

custom page.tpl.php for a drupal view

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

Include CSS or Javascript file for specific node in Drupal 6

What is the best method for including a CSS or Javascript file for a specific node in Drupal 6.
I want to create a page on my site that has a little javascript application running, so the CSS and javascript is specific to that page and would not want to be included in other page loads at all.
I'd advise against using hook_nodeapi for that. Adding CSS and Javascript is related to layout so hook_nodeapi is not the place for it: use themeing. This way, you can override those files when you're going to develop a new theme. Doing that with the nodeapi approach would be a bit harder (you'd have to search the js/css list for the files, remove them and replace them with your own).
Anyway: what you need to do is add a node preprocess function that adds those files for you. You can do this either in a module or in a custom theme. For a module this would be:
function mymodule_preprocess_node(&$variables) {
$node = $variables['node'];
if (!empty($node) && $node->nid == $the_specific_node_id) {
drupal_add_js(drupal_get_path('module', 'mymodule') . "/file.js", "module");
drupal_add_css(drupal_get_path('module', 'mymodule') . "/file.css", "module");
}
}
or for a theme:
function mytheme_preprocess_node(&$variables) {
$node = $variables['node'];
if (!empty($node) && $node->nid == $the_specific_node_id) {
drupal_add_js(path_to_theme() . "/file.js", "theme");
drupal_add_css(path_to_theme(). "/file.css", "theme");
}
}
Don't forget to clear the cache, first.
These functions are called before the node is themed. Specifing the js/css there allows for a cascaded approach: you can have the generic/basic stuff in the module and provide enhanced or specific functionality in the theme.
I use the preprocess functions but this has some issues. $variables['styles'] is usually set before the node preprocess function is called. In other words drupal_get_css is already called which makes you calling drupal_add_css useless. The same goes for drupal_add_js. I work around this by resetting the $variables['styles'] value.
function mytheme_preprocess_node(&$variables) {
$node = $variables['node'];
if (!empty($node) && $node->nid == $the_specific_node_id) {
drupal_add_js(path_to_theme() . "/file.js", "theme");
drupal_add_css(path_to_theme(). "/file.css", "theme");
$variables['styles'] = drupal_get_css();
$variables['script'] = drupal_get_js();
}
}
This seems to work for most cases.
P.S. There's hardly any ever need to create a module to solve a theming problem.
Cheers.
This seems like a good solution:
http://drupal.org/project/js_injector
and
http://drupal.org/project/css_injector
It works when you want to insert inline code into something other than technically a node so there's no node id and no PHP input option available. Like I used it to inject small jQuery tweaks into a couple of admin pages. It works by path rather than node id.
The best solution I've come up with so far is to enable the PHP input mode, and then call drupal_add_css and drupal_add_js as appropriate in a PHP block in the start of the body of your node.
This should do the trick - a quickie module that uses the hook_nodeapi to insert the JS/CSS when the node is viewed.
function mymodule_nodeapi(&$node, $op, $a3 = NULL, $a4 = NULL) {
// the node ID of the node you want to modify
$node_to_modify = 6;
// do it!
if($op == 'view' && $node->nid == $node_to_modify) {
drupal_add_js(drupal_get_path('module', 'mymodule') . '/mymodule.js');
drupal_add_css(drupal_get_path('module', 'mymodule') . '/mymodule.css');
}
}
This avoids security issues with enabling the PHP input filter, and doesn't require a separate node template file which could become outdated if you updated the main node template and forgot about your custom one.
You can have a custom template for that node (node-needsjs.tpl.php) which calls the javascript. That's a little cleaner than using PHP right in the node body, and makes changes to content easier in the future.
EDIT: I don't think I was very clear above. You want to name the template file node-(nodeid).tpl.php. So if it was Node 1, call the file node-1.tpl.php

Resources