Add class to drupal body - drupal

How can I add term id of all terms related to a node, to that node body class in drupal site?
For example, A node named stackoverflow is tagged with four terms
term1
term2
term3
term4
term5
I want to add these classed to node body class...
article-term-(term1tid)
article-term-(term2tid)
article-term-(term3tid)
article-term-(term4tid)
article-term-(term5tid)
These are pages I want to change their class names:
عکس نوزاد
عکس نوزاد
کاردستی
سوپ ساده
داستان برای کودک
کاردستی

leymannx code is really complete and fine.
But it does not contains all terms of a node.
I wrote this code and i wish it will be useful for you.
function YOURTHEME_preprocess_html(&$variables) {
if (arg(0) == 'node' && is_numeric(arg(1))) {
$node = node_load(arg(1));
$results = stackoverflow_taxonomy_node_get_terms($node);
if (is_array($results)) {
foreach ($results as $item) {
$variables['classes_array'][] = "article-term-" . $item->tid;
}
}
}
}
There is a function named ""stackoverflow_taxonomy_node_get_terms"" that returns all terms attached to a node.
function stackoverflow_taxonomy_node_get_terms($node, $key = 'tid'){
static $terms;
if (!isset($terms[$node->vid][$key])) {
$query = db_select('taxonomy_index', 'r');
$t_alias = $query->join('taxonomy_term_data', 't', 'r.tid = t.tid');
$v_alias = $query->join('taxonomy_vocabulary', 'v', 't.vid = v.vid');
$query->fields($t_alias);
$query->condition("r.nid", $node->nid);
$result = $query->execute();
$terms[$node->vid][$key] = array();
foreach ($result as $term) {
$terms[$node->vid][$key][$term->$key] = $term;
}
}
return $terms[$node->vid][$key];
}
i wish this code could be the best.
write all of this codes in template.php file in your theme.
if you want just some nodes have class name, add replace this part of code.
> if (arg(0) == 'node' && is_numeric(arg(1)) && ( arg(1)==X || arg(1)==Y
> ) ) {

As #P1ratRuleZZZ already pointed out template_preprocess_html (implemented from your sub-theme's template.php file) is the function to add body classes.
Thing is, that within this function, you need to load the actual node object first, then get the values of that term reference field, to finally add them as classes to the body tag.
Replace MYTHEME and field_MYFIELD with your names.
/**
* Implements template_preprocess_html().
*/
function MYTHEME_preprocess_html(&$variables) {
// Get the node.
if ($node = menu_get_object()) {
// Check node type.
if ($node->type === 'article') {
// Get taxonomy terms.
$terms = field_get_items('node', $node, 'field_MYFIELD');
foreach ($terms as $term) {
// Add body class.
$variables['classes_array'][] = 'article-term-' . $term['tid'];
}
}
}
}

Try to use template_preprocess_html()
this is in your theme's template.php file:
YOURTHEMENAME_preprocess_html(&$variables) {
$term_id = arg(1); // For example, or use some &drupal_static() to store a value while preprocessing from module
$variables['classes_array'][] = 'article-term-' . $term_id;
}
So as you can see it you shoud change template_ to your themename_ first

Related

hook_alter uc_addresses submit function in Drupal/Ubercart

I am trying to hook into uc_addresses submit function, but it has become very confusing very fast. Just to note this is Ubercart running on Drupal 6. So I've isolated the code in uc_addresses.module that I'm interested in hooking in to:
function uc_addresses_get_address_form_submit($form, &$form_state) {
global $user;
$address_user = $form['stored_values']['#value']['user'];
$address = $form['stored_values']['#value']['address'];
$view = $form['stored_values']['#value']['view'];
if ($form_state['clicked_button']['#value'] == t('Delete address')) {
cache_clear_all();
$form_state['redirect'] =
array('user/'. $address_user->uid .'/addresses/' . $address->aid . '/delete');
}
else {
if (!$address) {
$address = new stdClass();
$address->uid = $address_user->uid;
}
$valid = TRUE;
foreach (element_children($form_state['values']['panes']) as $pane_id) {
$func = _address_pane_data($pane_id, 'callback');
$isvalid = $func('process', $address, $form_state['values']['panes'][$pane_id]);
if ($isvalid === FALSE) {
$_SESSION['expanded_panes'][] = $key;
$valid = FALSE;
}
}
if ($view == 'edit') { // Update database
_uc_addresses_db_update_address($address);
}
elseif ($view == 'new' || $view == 'add') { // Insert into datebase
_uc_addresses_db_add_address($address);
}
$form_state['redirect'] = array('user/'. $address_user->uid .'/addresses');
}
}
The goal is to copy a portion of the submitted form values in the database. Which in itself may be an issue because I need to make sure my hook occurs after the values have been written to the table. So my question is what should my hook function look like if I want it to occur after this form has been submitted?
Okay so foolish me didn't realize that there is a huge section in the uc_addresses documention about hooks. Link to the documentation. In this specific case where you want to hook into form submissions I would recommend using hook_uc_addresses_address_insert() and hook_uc_addresses_address_update().

Generate url aliasing based on taxonomy term

I have a vocab category and four terms within it. what i want to do is if content is tagged with a termin in particular say "term1" to have the url generated as word1/[node:title] and for all the other tags just the standard url formatting.
If i wanted the term in the url obviously id use pattern replacement but i want another word to be used if a particular tag is used
I can't think of an easy plug-and-play way of achieving this. You may have to create your own token for the "Default path pattern" in Pathauto's URL alias settings:
/**
* Implementation of hook_token_info().
*/
function MODULE_token_info() {
$info['tokens']['node']['node-term-path'] = array(
'name' => t('Node path by term'),
'description' => t('The path to a node based on its taxonomy terms.'),
);
return $info;
}
/**
* Implementation of hook_tokens().
*/
function MODULE_tokens($type, $tokens, array $data = array(), array $options = array()) {
$replacements = array();
if ($type == 'node' && !empty($data['node'])) {
$node = $data['node'];
foreach ($tokens as $name => $original) {
switch ($name) {
case 'node-term-path':
$items = field_get_items('node', $node, 'TAXONOMY_FIELD_NAME');
foreach ($items as $item) {
$tids[] = $item['tid'];
}
if (in_array(TID_OF_TERM1, $tids)) {
// Path for nodes with term1
$replacements[$original] = 'word1/'. pathauto_cleanstring($node->title);
}
else {
// Path for other nodes
$replacements[$original] = 'content/'. pathauto_cleanstring($node->title);
}
break;
}
}
}
return $replacements;
}
Found a simple way actually to anyone who need a similar solution use the module Entity Reference.
http://drupal.org/project/entityreference
I just created a new field for the user account select entity reference then you can choose any entity within drupal to reference.
(ie so you can select a term/content/anything)

Nested relations in Drupal

I have a D7 website where users can make content (obviously...). So every node has it's own author. Every author is a member of an organization. But he can be a member of more then one organization. So far the facts.
I would like to create a view where the content is filtered on Author. Very easy, set the relation of the view on "Content's Author" and select the current user as filter.
But what I would like is to filter on the author's organization. So in fact it's a nested relation. Filter the nodes on the current logged in user (that's easy), but how can I filter on the current logged in user's organization?
Ok, the panels didn't work out, so I wrote my own hook :-)
function mymodule_views_pre_view (&$view, &$display_id, &$args) {
// Only execute this script when the view 'fiches_my_thema' is called
if ('fiches_my_thema' == $view->name) {
// Get users thema
global $user;
$userRoles = $user->roles;
$user_themas = array();
// Filter roles so you end up with the "Thema's".
foreach ($userRoles as $key) {
if(strpos($key,'edacteur')) {
$key = str_replace('Redacteur - ','', $key);
$key = str_replace('Eindredacteur - ','', $key);
$user_themas[] = $key;
}
}
// Resolve tid
$terms = taxonomy_get_tree(5);
$allRoles = array();
$arguments = array();
// Assign the 'tid' to a variable
foreach ($terms as $key) {
$singleRoles = $key->name;
$allRoles[] = $singleRoles;
if(in_array($singleRoles, $user_themas)) {
$arguments[] = $key->tid;
}
}
// Only when the arguments are NOT empty, set the arguments
if(!empty($arguments)) {
$finalArguments = implode("+", $arguments);
$args[] = "$finalArguments";
$view->set_arguments($args);
}
}
}

Drupal 7 - Insert taxonomy into node object

I have a script which successfully creates new nodes. But I'm having trouble setting the taxonomy before saving.
I believe in Drupal 6 I would use this method.
$cat1_tid = taxonomy_get_term_by_name($data[$i]['cat1']);
$cat2_tid = taxonomy_get_term_by_name($data[$i]['cat2']);
$cat3_tid = taxonomy_get_term_by_name($data[$i]['cat3']);
$node->taxonomy = array($cat1_tid, $cat2_tid, $cat3_tid);
I think in Drupal 7 I would do this (my field name is Catalog)
$node->taxonomy_catalog['und'][0] = array($term1Obj, $term2Obj);
taxonomy_get_term_by_name doesn't seem to return the correct object to insert into the node object.
If anyone can shed some light, appreciated.
Thanks
EDIT
Solution:
// Taxonomy
$categories = array($data[$i]['cat1'], $data[$i]['cat2'], $data[$i]['cat3']);
foreach ($categories as $key => $category) {
if ($term = taxonomy_get_term_by_name($category)) {
$terms_array = array_keys($term);
$node->taxonomy_catalog[LANGUAGE_NONE][$key]['tid'] = $terms_array['0'];
}
}
Below is some quick-and-dirty code I used recently to import "command" nodes into a site. Mid-way down, the foreach loop takes care of creating and assigning terms, as needed.
$command = new stdClass;
$command->language = LANGUAGE_NONE;
$command->uid = 1;
$command->type = 'drubnub';
$command->title = $line['0'];
$command->body[LANGUAGE_NONE]['0']['value'] = $line['1'];
$command->url[LANGUAGE_NONE]['0']['value'] = trim($line['2']);
$command->uses[LANGUAGE_NONE]['0']['value'] = $line['3'];
$tags = explode(',', $line['4']);
foreach ($tags as $key => $tag) {
if ($term = taxonomy_get_term_by_name($tag)) {
$terms_array = array_keys($term);
$command->field_tags[LANGUAGE_NONE][$key]['tid'] = $terms_array['0'];
} else {
$term = new STDClass();
$term->name = $tag;
$term->vid = 1;
if (!empty($term->name)) {
$test = taxonomy_term_save($term);
$term = taxonomy_get_term_by_name($tag);
foreach($term as $term_id){
$command->product_tags[LANGUAGE_NONE][$key]['tid'] = $term_id->tid;
}
$command->field_tags[LANGUAGE_NONE][$key]['tid'] = $tid;
}
}
}
node_save($command);
Here you are, this code successfully add a new term to the node before the node is created.
$my_term_name = 'micky';
$term_array = taxonomy_get_term_by_name($my_term_name);
if($term_array == array()){
//empty term ..
$term->name = $my_term_name;
$term->vid = 1;
taxonomy_term_save($term);
$term_array = taxonomy_get_term_by_name($my_term_name);
}
//get the first index of the array .
foreach ($term_array as $tid => $term_object)break;
$node->field_tag['und'][$tid] = (array)$term_object;
Perhaps my experience is unique, but I found that using
$term = taxonomy_get_term_by_name($tag)
$tid = $term->tid;
caused an error.
I found that after $term is saved, there is no need to fetch the newly created term.
The $term object is updated to include the new tid.
Any answer that use LANGUAGE_NONE or 'und' to alter a field is not the proper way of doing it as it assumes that the drupal site is one language. The proper way to edit a field is to use entity_metadata_wrapper.
$node_wrapper = entity_metadata_wrapper('node', $node);
// If you have Entity API [entity] module installed you can simply.
$node_wrapper = $node->wrapper();
// It is good practice to check the terms in the field before adding
// a new one to make sure that the term is not already set.
$term_ids_current = $node_wrapper->taxonomy_catalog->raw();
if (!in_array($term_new_id, $term_ids_current)) {
$node_wrapper->taxonomy_catalog[] = $term_new_id;
}
// To add multiple terms iterate an array or terms ids.
$term_ids_current = $node_wrapper->taxonomy_catalog->raw();
$tern_new_ids = array(1, 2, 3);
foreach ($term_new_ids as $term_new_id) {
if (!in_array($term_new_id, $term_ids_current)) {
$node_wrapper->taxonomy_catalog[] = $term_new_id;
}
}
// To remove a term.
$term_ids_current = $node_wrapper->taxonomy_catalog->raw();
$delta = array_search($term_remove_id, $term_ids_current);
if (is_int($delta)) {
$node_wrapper->taxonomy_catalog->offsetUnset($delta);
}
// To replace all terms.
$term_new_ids = array(1, 2, 3);
$node_wrapper->taxonomy_catalog->set($term_new_ids);
// To get all the fully loaded terms in a field.
$terms = $node_wrapper->taxonomy_catalog->value();
// At the end make sure to save it.
$node_wrapper->save();

drupal module, check if node type

As a more specific take on this question:
drupal jQuery 1.4 on specific pages
How do I check, inside a module, whether or not a node is a certain type to be able to do certain things to the node.
Thanks
The context:
I'm trying to adapt this code so that rather than working on 'my_page' it works on a node type.
function MYMODULE_preprocess_page(&$variables, $arg = 'my_page', $delta=0) {
// I needed a one hit wonder. Can be altered to use function arguments
// to increase it's flexibility.
if(arg($delta) == $arg) {
$scripts = drupal_add_js();
$css = drupal_add_css();
// Only do this for pages that have JavaScript on them.
if (!empty($variables['scripts'])) {
$path = drupal_get_path('module', 'admin_menu');
unset($scripts['module'][$path . '/admin_menu.js']);
$variables['scripts'] = drupal_get_js('header', $scripts);
}
// Similar process for CSS but there are 2 Css realted variables.
// $variables['css'] and $variables['styles'] are both used.
if (!empty($variables['css'])) {
$path = drupal_get_path('module', 'admin_menu');
unset($css['all']['module'][$path . '/admin_menu.css']);
unset($css['all']['module'][$path . '/admin_menu.color.css']);
$variables['styles'] = drupal_get_css($css);
}
}
}
Thanks.
Inside of a module, you can do this:
if (arg(0) == 'node' && is_numeric(arg(1)) && arg(2) != 'edit') {
if (!($node)) {
$node = node_load(arg(1));
}
if ($node->type == 'page') {
// some code here
}
}
That will load a node object given the current node page (if not available). Since I don't know the context of code you are working with, this is kind of a rough example, but you can always see properties of a node by doing node_load(node_id). But, depending on the Drupal API function, it may already be loaded for you.
For example, hook_nodeapi.
http://api.drupal.org/api/function/hook_nodeapi
You could do:
function mymodule_nodeapi(&$node, $op, $a3 = NULL, $a4 = NULL) {
switch ($op) {
case 'view':
// some code here
}
}
Try this:-
function MyModule_preprocess_node(&$vars) {
if ($vars['type'] == 'this_type') {
// do some stuff
}
}
Try this:-
$node = node_load(arg(1));
$node =$node->type;
if($node == 'node_type'){
//do something
}

Resources