Drupal theme preprocess function - primary links - drupal

I recently wrote a theme function to add a class to my primary links that works great. I then wrote some css classes to style these links with custom background images. Worked out great. Now comes the problem, the link text for the primary links still is displayed. Normally this isn't a problem as I would just wrap the in a with a custom "hide" class. For example:
<span class="hide">Link Text</span>
So my question is how can I loop through the primary links and wrap the text w/ a <span> like my example? Here's my theme function that I used to add my classes.
function zkc_preprocess_page(&$vars, $hook) {
// Make a shortcut for the primary links variables
$primary_links = $vars['primary_links'];
// Loop thru the menu, adding a new class for CSS selectors
$i = 1;
foreach ($primary_links as $link => $attributes){
// Append the new class to existing classes for each menu item
$class = $attributes['attributes']['class'] . " item-$i";
// Add revised classes back to the primary links temp variable
$primary_links[$link]['$attributes']['class'] = $class;
$i++;
} // end the foreach loop
// reset the variable to contain the new markup
$vars['primary_links'] = $primary_links;
}

Is jQuery an option?
Try something like this:
$(document).ready(function(){
$('#primary li a')
.wrapInner('<span class="hide">' + '</span>');
});
EDIT:
Or if you want to go Drupal, put this guy in your foreach loop:
$link['title'] = '<span class="hide">' . check_plain($link['title']) . '</span>';

If all you want is to hide the link text, why don't you just use something like text-indent: -9999px;?

The correct methods for altering the output of the menu links can be done at the theming layer. You were on the right path with the preprocessing hook use, but there is a little more to it.
Refer to this for more information:
http://drupal.org/node/352924#comment-1189890
http://api.drupal.org/api/function/theme_links/6

Typo?
$primary_links[$link]['$attributes']['class'] = $class;
Should read;
$primary_links[$link]['attributes']['class'] = $class;

Related

Can I change different logo for different pages in drupal

I want to change different logo for each different pages in drupal and I also want to hide logo for some pages too.How can I do that?I've already search possible answers and I didn't find any.
As was stated by MilanG, logo is rendered in your page template (default page.tpl.php or theme suggestion) using $logo variable. This variable is set in template_preprocess_page(), and the best way to change it is to use the same preprocess function in your theme:
function mytheme_preprocess_page(&$variables) {
$logo_path = '/' . drupal_get_path('theme', 'mytheme') . '/logos/';
// Alter logo under some conditions
if ($first_condition) {
$variables['logo'] = $logo_path . 'logo1.png';
} elseif ($second_condition) {
$variables['logo'] = $logo_path . 'logo2.png';
} elseif ($third_condition) {
// Hide logo. Your page.tpl.php must contain
// something like <?php if ($logo): ?>
$variables['logo'] = null;
}
// etc.
}
The "standard" way for printing logo is printing $logo variable from page.tpl.php template. But you don't have to do it that way at all.
I.e. you can add your php code which will alter logo html code the way you like.
Or, you can place logo html inside static blocks and set for every block on what pages should it appear (in block settings). And of course create "logo" region for your theme.

Add custom data-attribute to Wordpress navigation menu

I've seen some similar questions here on stackoverflow, but mine is a bit different..
I need to be able to add custom data attribute to wordpress menu.
The problem i've got is that all the solutions i found, like the following, for example:
add_filter( 'nav_menu_link_attributes', 'my_nav_menu_attribs', 10, 3 );
function my_nav_menu_attribs( $atts, $item, $args )
{
// The ID of the target menu item
$menu_target = 365;
// inspect $item
if ($item->ID == $menu_target) {
$atts['data-reveal-id'] = 'myModal';
}
return $atts;
}
allows you to add the same attribute to all menu items.
What i need, is actually a way to add the same data attribute, but with different values on each element on the list.
this is pretty much what i need to achive:
<ul id="myMenu">
<li data-menuanchor="firstPage" class="active">First section</li>
<li data-menuanchor="secondPage">Second section</li>
<li data-menuanchor="thirdPage">Third section</li>
<li data-menuanchor="fourthPage">Fourth section</li>
</ul>
because i need to use this plugin here: https://github.com/alvarotrigo/fullPage.js#fullpagejs
any advice?
Thanks
I guess the solution would be to extend the navigation items. I made this before to add icons to menu items.
Take a look over here - instead of a subheadline you cann name the field "anchortarget" (or anything else) and call it in your menu...
http://www.wpexplorer.com/adding-custom-attributes-to-wordpress-menus/
If you need further hints, you should google for "wordpress + menu + custom field".
Hope this helps you. All the best
At the end, I managed to solve this using javascript.
This is what I did:
(function() {
var arrayList, key, val;
arrayList = ['first', 'second', 'third', 'fourth'];
for (key in arrayList) {if (window.CP.shouldStopExecution(1)){break;}
val = arrayList[key];
console.log("key is " + key + " and val is " + val);
$('li').each(function(index) {
if (parseInt(index) === parseInt(key)) {
return $(this).attr('data-anchor', val);
}
});
}
window.CP.exitedLoop(1);
}).call(this);
Create an array with the data you need
Foreach loop to iterate trough the array
Inside that loop, loop trough the menu items
If the menu index is the same as the array index, append the array value as an attribute.
Here's a codepen example as well: http://codepen.io/NickHG/pen/GmKqqE
Ok, too bad, I am sorry. I would post the code I've written for my icons but the code ist like 400 lines with the walker and stuff. But as it seems you're using foundation, you should head over here -> https://www.smashingmagazine.com/2015/10/customize-tree-like-data-structures-wordpress-walker-class/
Even if you don't know about php or wordpress hooks this tutorial will absolutly explain every step needed to code it by hand. It works, I just tested it with my site by copy / pasting it.
If you scroll down, you'll see screenshots - they added an icon field (nearly like i did) how they did it and how they use it. After seeing this tut, honestly, I regret I made it all by myself. It was painfull - this tut just works like a charm....

Drupal - Add custom html in li to menu ul?

Is there any way to write some html (as you might in a block), and have that html appear as a menu item?
My situation is that I want some text that is not a link to say 'Follow us on:', and then I want 2 images which are both links to twitter and facebook.
Menu html cant do this as it requires any html you write to be part of a link, and to be the same link for that menu entry.
http://drupal.org/project/menu_html
I really want the html I add to be within the menu list.
Thanks
UPDATE
Code doesn't work well in the comments so im adding it here. This link seemed to be the closest to what you were suggesting:
http://api.drupal.org/api/drupal/includes--menu.inc/function/theme_menu_item/6
So I added this to my template.php:
function localhost_petitpim_menu_item($link, $has_children, $menu = '', $in_active_trail = FALSE, $extra_class = NULL) {
$class = ($menu ? 'expanded' : ($has_children ? 'collapsed' : 'leaf'));
if (!empty($extra_class)) {
$class .= ' ' . $extra_class;
}
if ($in_active_trail) {
$class .= 'active-trail myactive';
}
return '<li class="' . $class . '">' . $link . $menu . "</li>\n";
}
All ive done is add a class of 'myactive' so I can see if its working. My theme name is 'localhost_petitpim'. Ive refreshed the cache. My theme is set to 'Rebuild theme registry on every page.' I cant see the new class being applied. Have I done something wrong?
Thanks
You can simply hard-code text and linked images in your tpl.php file(s).
Just put html block with desired code in tpl.php after menu. Make new wraper around menu & block if current html structure of your theme is not supporting this solution. Block should be floated right or displayed inline depending on HTML+CSS of your theme.
Hope this helps.
Not a nice solution, but it works.
Add two dummy menu entrys to your menu.
Override the theme_menu_link method by implementing phptemplate_menu_link in your template.php file.
Inside the phptemplate_menu_link filter for your dummy entry and replace them with what ever html code you like.

Make a visible primary link not clickable

On my Drupal site I've got a set of Primary Links. The ones that expand I'd like to make the parent not click able e.g
-home
-about
-history
-website
Only home, history, website should link to a page. If the user clicks on aboutnothing should happen. I've tried searching around the admin panels as well as leaving the field blank but it doesn't seem to be working. I'd assume I'd have to hardcode this? If so, how?
Try this module http://drupal.org/project/special_menu_items
Its probably the simplest way to achieve what you want.
If you can live with it, the easiest solution is to use js to disable clicks.
Adding a yourtheme_menu_item function in template.php seems to be the way to go for this. The documentation for the original function is at http://api.drupal.org/api/function/theme_menu_item
The function passes a $has_children variable and a $menu variable, so it should be pretty easy to adjust Primary Menu items with children as needed.
Some untested example code:
function yourtheme_menu_item($link, $has_children, $menu = '', $in_active_trail = FALSE, $extra_class = NULL) {
// ... original theme code copy-pasted ...
if ($has_children) {
$modified_link_name = youtheme_write_menu_item_without_links($link);
return '<li class="'. $class .'">'. $modified_link_name ."</li>\n";
} else {
// From original function
return '<li class="'. $class .'">'. $link . $menu ."</li>\n";
}
}
You just need to add in the path the phrase <nolink>.
"You just need to add in the path the phrase <nolink>"
i used this before and it worked, but for some reason it didnĀ“t work for a different site that i am using now.
So i tried to write # in the path and worked fine for me.
Hug everybody.

Is it possible to *optionally* override a theme in Drupal 6?

I want to override the theming of only one (custom) menu. I can do this with phptemplate_menu_tree() but - of course - it overrides the rendering of all menus.
I've tried returning FALSE (an obvious technique IMO) if the menu is not the specific one I want to override - but this doesn't cause the overridden theme function to be called.
My only alternative (when the menu is anything other than the specific one) is to call the overridden function from within phptemplate_menu_tree() - but this seems to defeat the whole point of the override system, since the default rendering function will be hard-coded therein.
I hope the explanation is clear, and any help is greatly appreciated - tks.
UPDATE
For the sake of future reference, I'll explain how I solved this.
First off, the menu rendering starts with this function in menu.module:
function menu_block($op = 'list', $delta = 0) {
$menus = menu_get_menus();
// The Navigation menu is handled by the user module.
unset($menus['navigation']);
if ($op == 'list') {
$blocks = array();
foreach ($menus as $name => $title) {
// Default "Navigation" block is handled by user.module.
$blocks[$name]['info'] = check_plain($title);
// Menu blocks can't be cached because each menu item can have
// a custom access callback. menu.inc manages its own caching.
$blocks[$name]['cache'] = BLOCK_NO_CACHE;
}
return $blocks;
}
else if ($op == 'view') {
$data['subject'] = check_plain($menus[$delta]);
$data['content'] = menu_tree($delta);
return $data;
}
}
If you only want to override how individual item (links) are rendered then you can use the theme system (there are loads of references on how do this) - but if you want complete control on how the entire menu tree is rendered (for example, wrapping the output in nested DIVs so it can be centred on the page) then there is no way to override menu_block().
Therefore, I removed the menu I wanted to render differently from the administer blocks page (site building->blocks) and rendered the menu directly in my page.tpl.php using code something like this: (angle brackets removed)
$m = menu_tree_page_data('my-menu-id');
$o = "DIV";
foreach($m as $k => $v){
$o .= "SPAN {$v['link']['title']} /SPAN";
}
$o .= "/DIV";
echo $o;
I hope this helps.
I've had mixed success doing template.php menu overrides to force CSS classes and ids or HTML into the output.
You could make use of Block Theme when enabling the menu as a block, but I've never tried it.
http://drupal.org/project/blocktheme
If you want to tackle the template way, here are the zen menu override funcitons...
function zen_menu_item_link($link) {
if (empty($link['localized_options'])) {
$link['localized_options'] = array();
}
// If an item is a LOCAL TASK, render it as a tab
if ($link['type'] & MENU_IS_LOCAL_TASK) {
$link['title'] = '<span class="tab">' . check_plain($link['title']) . '</span>';
$link['localized_options']['html'] = TRUE;
}
return l($link['title'], $link['href'], $link['localized_options']);
}
function zen_menu_local_tasks() {
$output = '';
if ($primary = menu_primary_local_tasks()) {
$output .= '<ul class="tabs primary clear-block">' . $primary . '</ul>';
}
if ($secondary = menu_secondary_local_tasks()) {
$output .= '<ul class="tabs secondary clear-block">' . $secondary . '</ul>';
}
return $output;
}
You could use sections module, or look at how it switches theme for certain menu-items.
what I did was register a new theme function in my template.php called primary_links (because I wanted to only customize this menu in certain way) created the function mytheme_primary_links() in my template.php refreshed the cache so Drupal would add my theme function to the system then changed theme function on primary_links from links to my custom theme function primary_links - this allows me to customize only this 1 menu - could you do this and hook into where ever to change the theme function being called for your links?
Chris

Resources