Tweaks: Drupal, Wordpress, jQuery, Responsive development and LAMP
This blog post has tweaks, snippets or fixes not in their detail versions but aid in rapid prototyping during development. Focused around Drupal 7, Wordpress, jQuery, Zurb Foundation and LAMP.
Drupal navigation menu with Foundation 3
Drupal navigation menu's don't work out-of-the-box when working with responsive framework like Zurb Foundation, Twitter Bootstrap or any other flavours you fancy. This tweak works on Zurb Foundation 3 horizontal navigation menu. It should also work with Foundation 4 with some changes.
// Inside your template.php MYTHEME_preprocess_page() function modify main_menu
if (isset($vars['main_menu'])) {
$vars['primary_nav'] = theme('links__system_main_menu', array(
'links' => $vars['main_menu'],
'attributes' => array(
'class' => array('nav-bar'), // Add nav-bar class
)
));
}
Then override menu markup with:
/*
* Change rendering for main menu
*/
function MYTHEME_menu_tree__main_menu(&$variables){
$tree = $variables['tree'];
// If there are sub menus change their class to flyout and has-flyout for expanded menus
$tree = str_replace(array('nav-bar', 'expanded'), array('flyout', 'expanded has-flyout'), $tree);
return '
';
}
This only changes rendering for menu tree. Add one more function for drop-down menus on small screen:
/*
* Overrides theme menu item
*/
function MYTHEME_menu_link__main_menu(array $variables) {
$element = $variables['element'];
$sub_menu = '';
if ($element['#below']) {
$sub_menu = ' ' . drupal_render($element['#below']);
}
$output = l($element['#title'], $element['#href'], $element['#localized_options']);
return '' . $output . $sub_menu . " \n";
}
And you'll have a fully working Foundation 3 navigation menu markup in your Drupal menu. For vertical navigation try this:
/*
* Change rendering for user navigation menu
*/
function MYTHEME_menu_tree__navigation(&$variables){
$tree = $variables['tree'];
// If there are sub menus change their class to flyout and has-flyout for expanded menus
$tree = str_replace(array('nav-bar', 'expanded', 'vertical'), array('flyout', 'has-flyout', 'right'), $tree);
return '
';
}
Support for multiple level menus was introduced in Foundation 4. But below tweaks in JS and CSS might render them correctly to some extent.
// Contributed on Github @ https://github.com/zurb/foundation/issues/1209
.flyout .flyout {
left: 245px;
top: 100%;
margin-top: -65px;
}
// Contributed on Github @ https://github.com/zurb/foundation/issues/1209
jQuery('.nav-bar .has-flyout .flyout .has-flyout').hover(
function() {
jQuery(this).find('ul.flyout').show();
},
function() {
jQuery(this).find('ul.flyout').hide();
});
Drupal breadcrumbs with Foundation 3
Theme default Drupal breadcrumbs with Foundation:
/**
* Return a themed breadcrumb trail.
*
* @param $breadcrumb
* An array containing the breadcrumb links.
* @return a string containing the breadcrumb output.
*/
function MYTHEME_breadcrumb($variables) {
$breadcrumb = $variables['breadcrumb'];
$prefix = '';
$suffix = '';
$output = '';
//-- Add the active trail to breadcrumb
$active_title = drupal_get_title();
$breadcrumb[] = @l($active_title, drupal_get_destination(), array('attributes' => array('class' => 'active', 'title' => $active_title), 'html' => TRUE));
//dpr($breadcrumb);
$prefix .= '' . "\n";
if (!empty($breadcrumb)) {
foreach($breadcrumb as $item):
if (strpos($item, '"active"') > 0) $class = ' class="current"'; else $class = '';
$output .= '' . $item . ' ' . "\n";
endforeach;
return $prefix . $output . $suffix;
}
}
Smooth Scroll Foundation 4 Section
This tweak popped out when I had too much content organized in an Accordion. Foundation 4 Section works fine but with lot of contents it can probably confuse an avid user scrolling up and down everytime they click-open an Accordion. So here's a little plugin that takes care of that and you can apply distinction to certain devices by using media queries in the option.
/*!
* jFSectionScroll - Extension to Foundation Section plugin
* Examples and documentation at: https://www.ravendevelopers.com/blog/2013/04/tweaks-drupal-wordpress-jquery-responsive-development-and-lamp
* Author: Anirudh K. Mahant
* Requires: jQuery v1.2.6+
*/
(function ($) {
$.fn.jFSectionScroll = function (options) {
var defaults = {
mediaQuery: true
};
options = jQuery.extend(defaults, options);
return this.each(function (i) {
$(this).click(function(){
var clickElem = $(this);
setTimeout(function(){
if ($(clickElem).next('div.content').is(':visible') === true && options.mediaQuery){
smoothScroll(clickElem.parent());
}
}, 200);
});
});
};
})(jQuery);
/**
* Smoothscroll to the element passed as argument
*/
function smoothScroll(scrollElement){
$(scrollElement).ready(function(){
var destination = $(scrollElement).offset().top;
$("html:not(:animated),body:not(:animated)").animate({ scrollTop: destination-20}, 2000 );
});
}
The use of media query in option makes sense as certain devices such as a large screen rarely needs auto-scrolling. Another scenario would be Section - Vertical Tabs which turn to Accordions on smaller devices which is where it should auto-scroll. So initialize the plugin like below with or without a media query:
$(document).ready(function(){
// Initialize smooth auto scroll for accordion
$('div.section-container.accordion h5').jFSectionScroll();
// Initialize smooth auto scroll for vertical tabs applied only on smaller devices (Smartphones)
$('div.section-container.vertical-tabs h5').jFSectionScroll({
mediaQuery: Modernizr.mq('only screen and (min-width: 320px) and (max-width: 767px)')
});
});
This article also uses similar interaction if you click on one of the topics.
Redirecting Drupal 7 theme template
Sounds known? It is! Often, D7 default templates render un-necessary markup; creating pile of templates for each makes it insanely difficult to maintain your code. You can use preprocess function's inside your template.php to redirect specific regions, blocks, fields, views or panels to a common template. For eg. to redirect certain blocks to a single common template:
/**
* Override or insert variables into the block template.
*/
function MYTHEME_preprocess_block(&$vars) {
$vars['title_attributes_array']['class'][] = 'title';
$vars['classes_array'][] = 'clearfix';
$block_id = $vars['block_html_id'];
// We need simple blocks with less markup
switch($block_id):
case 'block-views-home-block';
case 'block-views-promotion-block';
$vars['theme_hook_suggestions'][] = 'block__nowrap_notitle';
break;
endswitch;
}
Clear your caches and this simply tells D7 to use block--nowrap--notitle.tpl.php template for given block_id.
jQuery Featured Carousel with Lightbox
jQuery Featured Carousel works much like any 3D Flash carousel. While it has great features; one that's really needed is integration with Lightbox. Events can be propagated to further tweak or control gestures like movedToCenter, leavingCenter and clickedCenter. This tweak works on Slimbox with Featured Carousel.
var slimboxSettings = {
overlayOpacity: 0.8,
resizeEasing: "easeInOutBack",
resizeDuration: 900,
imageFadeDuration: 600,
captionAnimationDuration: 1,
counterText: "Image {x} of {y}",
closeKeys: [27, 70],
nextKeys: [39, 83]
};
jQuery("#carousel").featureCarousel({
preload: true,
smallFeatureWidth: 0.7,
smallFeatureHeight: 0.7,
smallFeatureOffset: 40,
sidePadding: 30,
autoPlay: 10000,
trackerIndividual: false,
trackerSummation: false,
animationEasing: 'easeInOutBack',
movedToCenter: function($feature) {
// Find link to image
$feature.find('.carousel-image').parent().click(function(){
// Bind click event to Slimbox
jQuery.slimbox(jQuery(this).attr('href'), $feature.find('.carousel-image').attr('title'), slimboxSettings);
return false;
});
},
leavingCenter: function($feature) {
// Remove click event to restore default behavior
$feature.find('.carousel-image').parent().unbind('click');
}
});
Add custom body classes in Wordpress
Wordpress does that by default like on home page it adds home class to body. For CSS the distinction between home and not-home makes sense. Put this snippet in your template.php and it will do so:
//-- Add page specific CSS class to body
add_filter('body_class','theme_filter_body_class');
function theme_filter_body_class($classes) {
global $wp_query;
$classes[] = $wp_query->query_vars['name'];
if (!is_front_page()) $classes[] = 'inner';
return $classes;
}
This function will add inner class to body when viewing inner page's of your blog. Using $wp_query you can add more custom classes. With CSS3 this becomes lot easier with body:not(.home) but let's just stick to good old school way while CSS3 catches up.
Add custom image sizes in Wordpress
Managing and rendering images at different sizes in Wordpress is not as good as Drupal. Come Worpress 3.x it introduced fair bit of API to achieve this. Use this inside your template.php and bedazzled:
function MYTHEME_setup() {
global $wp_styles, $image_dimensions;
// This theme uses post thumbnails
add_theme_support('post-thumbnails');
if ( function_exists( 'add_image_size' ) ) {
add_image_size('category-blog-featured-image-thumb', 180, 180, TRUE); //-- Custom Thumbnail config for Blog Featured images
add_image_size('our-team-featured-image-thumb', 130, 130, TRUE); //-- Custom Thumbnail config for Our Team Featured images
add_image_size('testimonials-featured-image-thumb', 53, 53, TRUE); //-- Custom Thumbnail config for Testimonials images
}
}
When comes rendering images at particular size use this in one of your theme templates:
the_post_thumbnail('category-blog-featured-image-thumb');
the_post_thumbnail('our-team-featured-image-thumb');
the_post_thumbnail('testimonials-featured-image-thumb');
Creating SSL certificate in OpenSuSE 12.2
Fire up your command line as SUDO and type:
openssl req -new -x509 -key privkey.pem -out cacert.pem -days 1095
This generates your prerequisites before creating actual certificate. One more step to go:
openssl req -new -newkey rsa:2048 -nodes -keyout /etc/apache2/ssl.key/server.key -out /etc/apache2/ssl.csr/server.csr -days 1095
This works only if you have OpenSSL and mod_ssl installed and enabled. Restart Apache and browse https://localhost to confirm.
More tweaks on the way...