Wordpress 3.5
[autoinstalls/wordpress.git] / wp-content / themes / twentyeleven / functions.php
1 <?php
2 /**
3  * Twenty Eleven functions and definitions
4  *
5  * Sets up the theme and provides some helper functions. Some helper functions
6  * are used in the theme as custom template tags. Others are attached to action and
7  * filter hooks in WordPress to change core functionality.
8  *
9  * The first function, twentyeleven_setup(), sets up the theme by registering support
10  * for various features in WordPress, such as post thumbnails, navigation menus, and the like.
11  *
12  * When using a child theme (see http://codex.wordpress.org/Theme_Development and
13  * http://codex.wordpress.org/Child_Themes), you can override certain functions
14  * (those wrapped in a function_exists() call) by defining them first in your child theme's
15  * functions.php file. The child theme's functions.php file is included before the parent
16  * theme's file, so the child theme functions would be used.
17  *
18  * Functions that are not pluggable (not wrapped in function_exists()) are instead attached
19  * to a filter or action hook. The hook can be removed by using remove_action() or
20  * remove_filter() and you can attach your own function to the hook.
21  *
22  * We can remove the parent theme's hook only after it is attached, which means we need to
23  * wait until setting up the child theme:
24  *
25  * <code>
26  * add_action( 'after_setup_theme', 'my_child_theme_setup' );
27  * function my_child_theme_setup() {
28  *     // We are providing our own filter for excerpt_length (or using the unfiltered value)
29  *     remove_filter( 'excerpt_length', 'twentyeleven_excerpt_length' );
30  *     ...
31  * }
32  * </code>
33  *
34  * For more information on hooks, actions, and filters, see http://codex.wordpress.org/Plugin_API.
35  *
36  * @package WordPress
37  * @subpackage Twenty_Eleven
38  * @since Twenty Eleven 1.0
39  */
40
41 /**
42  * Set the content width based on the theme's design and stylesheet.
43  */
44 if ( ! isset( $content_width ) )
45         $content_width = 584;
46
47 /**
48  * Tell WordPress to run twentyeleven_setup() when the 'after_setup_theme' hook is run.
49  */
50 add_action( 'after_setup_theme', 'twentyeleven_setup' );
51
52 if ( ! function_exists( 'twentyeleven_setup' ) ):
53 /**
54  * Sets up theme defaults and registers support for various WordPress features.
55  *
56  * Note that this function is hooked into the after_setup_theme hook, which runs
57  * before the init hook. The init hook is too late for some features, such as indicating
58  * support post thumbnails.
59  *
60  * To override twentyeleven_setup() in a child theme, add your own twentyeleven_setup to your child theme's
61  * functions.php file.
62  *
63  * @uses load_theme_textdomain() For translation/localization support.
64  * @uses add_editor_style() To style the visual editor.
65  * @uses add_theme_support() To add support for post thumbnails, automatic feed links, custom headers
66  *      and backgrounds, and post formats.
67  * @uses register_nav_menus() To add support for navigation menus.
68  * @uses register_default_headers() To register the default custom header images provided with the theme.
69  * @uses set_post_thumbnail_size() To set a custom post thumbnail size.
70  *
71  * @since Twenty Eleven 1.0
72  */
73 function twentyeleven_setup() {
74
75         /* Make Twenty Eleven available for translation.
76          * Translations can be added to the /languages/ directory.
77          * If you're building a theme based on Twenty Eleven, use a find and replace
78          * to change 'twentyeleven' to the name of your theme in all the template files.
79          */
80         load_theme_textdomain( 'twentyeleven', get_template_directory() . '/languages' );
81
82         // This theme styles the visual editor with editor-style.css to match the theme style.
83         add_editor_style();
84
85         // Load up our theme options page and related code.
86         require( get_template_directory() . '/inc/theme-options.php' );
87
88         // Grab Twenty Eleven's Ephemera widget.
89         require( get_template_directory() . '/inc/widgets.php' );
90
91         // Add default posts and comments RSS feed links to <head>.
92         add_theme_support( 'automatic-feed-links' );
93
94         // This theme uses wp_nav_menu() in one location.
95         register_nav_menu( 'primary', __( 'Primary Menu', 'twentyeleven' ) );
96
97         // Add support for a variety of post formats
98         add_theme_support( 'post-formats', array( 'aside', 'link', 'gallery', 'status', 'quote', 'image' ) );
99
100         $theme_options = twentyeleven_get_theme_options();
101         if ( 'dark' == $theme_options['color_scheme'] )
102                 $default_background_color = '1d1d1d';
103         else
104                 $default_background_color = 'e2e2e2';
105
106         // Add support for custom backgrounds.
107         add_theme_support( 'custom-background', array(
108                 // Let WordPress know what our default background color is.
109                 // This is dependent on our current color scheme.
110                 'default-color' => $default_background_color,
111         ) );
112
113         // This theme uses Featured Images (also known as post thumbnails) for per-post/per-page Custom Header images
114         add_theme_support( 'post-thumbnails' );
115
116         // Add support for custom headers.
117         $custom_header_support = array(
118                 // The default header text color.
119                 'default-text-color' => '000',
120                 // The height and width of our custom header.
121                 'width' => apply_filters( 'twentyeleven_header_image_width', 1000 ),
122                 'height' => apply_filters( 'twentyeleven_header_image_height', 288 ),
123                 // Support flexible heights.
124                 'flex-height' => true,
125                 // Random image rotation by default.
126                 'random-default' => true,
127                 // Callback for styling the header.
128                 'wp-head-callback' => 'twentyeleven_header_style',
129                 // Callback for styling the header preview in the admin.
130                 'admin-head-callback' => 'twentyeleven_admin_header_style',
131                 // Callback used to display the header preview in the admin.
132                 'admin-preview-callback' => 'twentyeleven_admin_header_image',
133         );
134
135         add_theme_support( 'custom-header', $custom_header_support );
136
137         if ( ! function_exists( 'get_custom_header' ) ) {
138                 // This is all for compatibility with versions of WordPress prior to 3.4.
139                 define( 'HEADER_TEXTCOLOR', $custom_header_support['default-text-color'] );
140                 define( 'HEADER_IMAGE', '' );
141                 define( 'HEADER_IMAGE_WIDTH', $custom_header_support['width'] );
142                 define( 'HEADER_IMAGE_HEIGHT', $custom_header_support['height'] );
143                 add_custom_image_header( $custom_header_support['wp-head-callback'], $custom_header_support['admin-head-callback'], $custom_header_support['admin-preview-callback'] );
144                 add_custom_background();
145         }
146
147         // We'll be using post thumbnails for custom header images on posts and pages.
148         // We want them to be the size of the header image that we just defined
149         // Larger images will be auto-cropped to fit, smaller ones will be ignored. See header.php.
150         set_post_thumbnail_size( $custom_header_support['width'], $custom_header_support['height'], true );
151
152         // Add Twenty Eleven's custom image sizes.
153         // Used for large feature (header) images.
154         add_image_size( 'large-feature', $custom_header_support['width'], $custom_header_support['height'], true );
155         // Used for featured posts if a large-feature doesn't exist.
156         add_image_size( 'small-feature', 500, 300 );
157
158         // Default custom headers packaged with the theme. %s is a placeholder for the theme template directory URI.
159         register_default_headers( array(
160                 'wheel' => array(
161                         'url' => '%s/images/headers/wheel.jpg',
162                         'thumbnail_url' => '%s/images/headers/wheel-thumbnail.jpg',
163                         /* translators: header image description */
164                         'description' => __( 'Wheel', 'twentyeleven' )
165                 ),
166                 'shore' => array(
167                         'url' => '%s/images/headers/shore.jpg',
168                         'thumbnail_url' => '%s/images/headers/shore-thumbnail.jpg',
169                         /* translators: header image description */
170                         'description' => __( 'Shore', 'twentyeleven' )
171                 ),
172                 'trolley' => array(
173                         'url' => '%s/images/headers/trolley.jpg',
174                         'thumbnail_url' => '%s/images/headers/trolley-thumbnail.jpg',
175                         /* translators: header image description */
176                         'description' => __( 'Trolley', 'twentyeleven' )
177                 ),
178                 'pine-cone' => array(
179                         'url' => '%s/images/headers/pine-cone.jpg',
180                         'thumbnail_url' => '%s/images/headers/pine-cone-thumbnail.jpg',
181                         /* translators: header image description */
182                         'description' => __( 'Pine Cone', 'twentyeleven' )
183                 ),
184                 'chessboard' => array(
185                         'url' => '%s/images/headers/chessboard.jpg',
186                         'thumbnail_url' => '%s/images/headers/chessboard-thumbnail.jpg',
187                         /* translators: header image description */
188                         'description' => __( 'Chessboard', 'twentyeleven' )
189                 ),
190                 'lanterns' => array(
191                         'url' => '%s/images/headers/lanterns.jpg',
192                         'thumbnail_url' => '%s/images/headers/lanterns-thumbnail.jpg',
193                         /* translators: header image description */
194                         'description' => __( 'Lanterns', 'twentyeleven' )
195                 ),
196                 'willow' => array(
197                         'url' => '%s/images/headers/willow.jpg',
198                         'thumbnail_url' => '%s/images/headers/willow-thumbnail.jpg',
199                         /* translators: header image description */
200                         'description' => __( 'Willow', 'twentyeleven' )
201                 ),
202                 'hanoi' => array(
203                         'url' => '%s/images/headers/hanoi.jpg',
204                         'thumbnail_url' => '%s/images/headers/hanoi-thumbnail.jpg',
205                         /* translators: header image description */
206                         'description' => __( 'Hanoi Plant', 'twentyeleven' )
207                 )
208         ) );
209 }
210 endif; // twentyeleven_setup
211
212 if ( ! function_exists( 'twentyeleven_header_style' ) ) :
213 /**
214  * Styles the header image and text displayed on the blog
215  *
216  * @since Twenty Eleven 1.0
217  */
218 function twentyeleven_header_style() {
219         $text_color = get_header_textcolor();
220
221         // If no custom options for text are set, let's bail.
222         if ( $text_color == HEADER_TEXTCOLOR )
223                 return;
224
225         // If we get this far, we have custom styles. Let's do this.
226         ?>
227         <style type="text/css">
228         <?php
229                 // Has the text been hidden?
230                 if ( 'blank' == $text_color ) :
231         ?>
232                 #site-title,
233                 #site-description {
234                         position: absolute !important;
235                         clip: rect(1px 1px 1px 1px); /* IE6, IE7 */
236                         clip: rect(1px, 1px, 1px, 1px);
237                 }
238         <?php
239                 // If the user has set a custom color for the text use that
240                 else :
241         ?>
242                 #site-title a,
243                 #site-description {
244                         color: #<?php echo $text_color; ?> !important;
245                 }
246         <?php endif; ?>
247         </style>
248         <?php
249 }
250 endif; // twentyeleven_header_style
251
252 if ( ! function_exists( 'twentyeleven_admin_header_style' ) ) :
253 /**
254  * Styles the header image displayed on the Appearance > Header admin panel.
255  *
256  * Referenced via add_theme_support('custom-header') in twentyeleven_setup().
257  *
258  * @since Twenty Eleven 1.0
259  */
260 function twentyeleven_admin_header_style() {
261 ?>
262         <style type="text/css">
263         .appearance_page_custom-header #headimg {
264                 border: none;
265         }
266         #headimg h1,
267         #desc {
268                 font-family: "Helvetica Neue", Arial, Helvetica, "Nimbus Sans L", sans-serif;
269         }
270         #headimg h1 {
271                 margin: 0;
272         }
273         #headimg h1 a {
274                 font-size: 32px;
275                 line-height: 36px;
276                 text-decoration: none;
277         }
278         #desc {
279                 font-size: 14px;
280                 line-height: 23px;
281                 padding: 0 0 3em;
282         }
283         <?php
284                 // If the user has set a custom color for the text use that
285                 if ( get_header_textcolor() != HEADER_TEXTCOLOR ) :
286         ?>
287                 #site-title a,
288                 #site-description {
289                         color: #<?php echo get_header_textcolor(); ?>;
290                 }
291         <?php endif; ?>
292         #headimg img {
293                 max-width: 1000px;
294                 height: auto;
295                 width: 100%;
296         }
297         </style>
298 <?php
299 }
300 endif; // twentyeleven_admin_header_style
301
302 if ( ! function_exists( 'twentyeleven_admin_header_image' ) ) :
303 /**
304  * Custom header image markup displayed on the Appearance > Header admin panel.
305  *
306  * Referenced via add_theme_support('custom-header') in twentyeleven_setup().
307  *
308  * @since Twenty Eleven 1.0
309  */
310 function twentyeleven_admin_header_image() { ?>
311         <div id="headimg">
312                 <?php
313                 $color = get_header_textcolor();
314                 $image = get_header_image();
315                 if ( $color && $color != 'blank' )
316                         $style = ' style="color:#' . $color . '"';
317                 else
318                         $style = ' style="display:none"';
319                 ?>
320                 <h1><a id="name"<?php echo $style; ?> onclick="return false;" href="<?php echo esc_url( home_url( '/' ) ); ?>"><?php bloginfo( 'name' ); ?></a></h1>
321                 <div id="desc"<?php echo $style; ?>><?php bloginfo( 'description' ); ?></div>
322                 <?php if ( $image ) : ?>
323                         <img src="<?php echo esc_url( $image ); ?>" alt="" />
324                 <?php endif; ?>
325         </div>
326 <?php }
327 endif; // twentyeleven_admin_header_image
328
329 /**
330  * Sets the post excerpt length to 40 words.
331  *
332  * To override this length in a child theme, remove the filter and add your own
333  * function tied to the excerpt_length filter hook.
334  */
335 function twentyeleven_excerpt_length( $length ) {
336         return 40;
337 }
338 add_filter( 'excerpt_length', 'twentyeleven_excerpt_length' );
339
340 if ( ! function_exists( 'twentyeleven_continue_reading_link' ) ) :
341 /**
342  * Returns a "Continue Reading" link for excerpts
343  */
344 function twentyeleven_continue_reading_link() {
345         return ' <a href="'. esc_url( get_permalink() ) . '">' . __( 'Continue reading <span class="meta-nav">&rarr;</span>', 'twentyeleven' ) . '</a>';
346 }
347 endif; // twentyeleven_continue_reading_link
348
349 /**
350  * Replaces "[...]" (appended to automatically generated excerpts) with an ellipsis and twentyeleven_continue_reading_link().
351  *
352  * To override this in a child theme, remove the filter and add your own
353  * function tied to the excerpt_more filter hook.
354  */
355 function twentyeleven_auto_excerpt_more( $more ) {
356         return ' &hellip;' . twentyeleven_continue_reading_link();
357 }
358 add_filter( 'excerpt_more', 'twentyeleven_auto_excerpt_more' );
359
360 /**
361  * Adds a pretty "Continue Reading" link to custom post excerpts.
362  *
363  * To override this link in a child theme, remove the filter and add your own
364  * function tied to the get_the_excerpt filter hook.
365  */
366 function twentyeleven_custom_excerpt_more( $output ) {
367         if ( has_excerpt() && ! is_attachment() ) {
368                 $output .= twentyeleven_continue_reading_link();
369         }
370         return $output;
371 }
372 add_filter( 'get_the_excerpt', 'twentyeleven_custom_excerpt_more' );
373
374 /**
375  * Get our wp_nav_menu() fallback, wp_page_menu(), to show a home link.
376  */
377 function twentyeleven_page_menu_args( $args ) {
378         if ( ! isset( $args['show_home'] ) )
379                 $args['show_home'] = true;
380         return $args;
381 }
382 add_filter( 'wp_page_menu_args', 'twentyeleven_page_menu_args' );
383
384 /**
385  * Register our sidebars and widgetized areas. Also register the default Epherma widget.
386  *
387  * @since Twenty Eleven 1.0
388  */
389 function twentyeleven_widgets_init() {
390
391         register_widget( 'Twenty_Eleven_Ephemera_Widget' );
392
393         register_sidebar( array(
394                 'name' => __( 'Main Sidebar', 'twentyeleven' ),
395                 'id' => 'sidebar-1',
396                 'before_widget' => '<aside id="%1$s" class="widget %2$s">',
397                 'after_widget' => "</aside>",
398                 'before_title' => '<h3 class="widget-title">',
399                 'after_title' => '</h3>',
400         ) );
401
402         register_sidebar( array(
403                 'name' => __( 'Showcase Sidebar', 'twentyeleven' ),
404                 'id' => 'sidebar-2',
405                 'description' => __( 'The sidebar for the optional Showcase Template', 'twentyeleven' ),
406                 'before_widget' => '<aside id="%1$s" class="widget %2$s">',
407                 'after_widget' => "</aside>",
408                 'before_title' => '<h3 class="widget-title">',
409                 'after_title' => '</h3>',
410         ) );
411
412         register_sidebar( array(
413                 'name' => __( 'Footer Area One', 'twentyeleven' ),
414                 'id' => 'sidebar-3',
415                 'description' => __( 'An optional widget area for your site footer', 'twentyeleven' ),
416                 'before_widget' => '<aside id="%1$s" class="widget %2$s">',
417                 'after_widget' => "</aside>",
418                 'before_title' => '<h3 class="widget-title">',
419                 'after_title' => '</h3>',
420         ) );
421
422         register_sidebar( array(
423                 'name' => __( 'Footer Area Two', 'twentyeleven' ),
424                 'id' => 'sidebar-4',
425                 'description' => __( 'An optional widget area for your site footer', 'twentyeleven' ),
426                 'before_widget' => '<aside id="%1$s" class="widget %2$s">',
427                 'after_widget' => "</aside>",
428                 'before_title' => '<h3 class="widget-title">',
429                 'after_title' => '</h3>',
430         ) );
431
432         register_sidebar( array(
433                 'name' => __( 'Footer Area Three', 'twentyeleven' ),
434                 'id' => 'sidebar-5',
435                 'description' => __( 'An optional widget area for your site footer', 'twentyeleven' ),
436                 'before_widget' => '<aside id="%1$s" class="widget %2$s">',
437                 'after_widget' => "</aside>",
438                 'before_title' => '<h3 class="widget-title">',
439                 'after_title' => '</h3>',
440         ) );
441 }
442 add_action( 'widgets_init', 'twentyeleven_widgets_init' );
443
444 if ( ! function_exists( 'twentyeleven_content_nav' ) ) :
445 /**
446  * Display navigation to next/previous pages when applicable
447  */
448 function twentyeleven_content_nav( $html_id ) {
449         global $wp_query;
450
451         if ( $wp_query->max_num_pages > 1 ) : ?>
452                 <nav id="<?php echo esc_attr( $html_id ); ?>">
453                         <h3 class="assistive-text"><?php _e( 'Post navigation', 'twentyeleven' ); ?></h3>
454                         <div class="nav-previous"><?php next_posts_link( __( '<span class="meta-nav">&larr;</span> Older posts', 'twentyeleven' ) ); ?></div>
455                         <div class="nav-next"><?php previous_posts_link( __( 'Newer posts <span class="meta-nav">&rarr;</span>', 'twentyeleven' ) ); ?></div>
456                 </nav><!-- #nav-above -->
457         <?php endif;
458 }
459 endif; // twentyeleven_content_nav
460
461 /**
462  * Return the URL for the first link found in the post content.
463  *
464  * @since Twenty Eleven 1.0
465  * @return string|bool URL or false when no link is present.
466  */
467 function twentyeleven_url_grabber() {
468         if ( ! preg_match( '/<a\s[^>]*?href=[\'"](.+?)[\'"]/is', get_the_content(), $matches ) )
469                 return false;
470
471         return esc_url_raw( $matches[1] );
472 }
473
474 /**
475  * Count the number of footer sidebars to enable dynamic classes for the footer
476  */
477 function twentyeleven_footer_sidebar_class() {
478         $count = 0;
479
480         if ( is_active_sidebar( 'sidebar-3' ) )
481                 $count++;
482
483         if ( is_active_sidebar( 'sidebar-4' ) )
484                 $count++;
485
486         if ( is_active_sidebar( 'sidebar-5' ) )
487                 $count++;
488
489         $class = '';
490
491         switch ( $count ) {
492                 case '1':
493                         $class = 'one';
494                         break;
495                 case '2':
496                         $class = 'two';
497                         break;
498                 case '3':
499                         $class = 'three';
500                         break;
501         }
502
503         if ( $class )
504                 echo 'class="' . $class . '"';
505 }
506
507 if ( ! function_exists( 'twentyeleven_comment' ) ) :
508 /**
509  * Template for comments and pingbacks.
510  *
511  * To override this walker in a child theme without modifying the comments template
512  * simply create your own twentyeleven_comment(), and that function will be used instead.
513  *
514  * Used as a callback by wp_list_comments() for displaying the comments.
515  *
516  * @since Twenty Eleven 1.0
517  */
518 function twentyeleven_comment( $comment, $args, $depth ) {
519         $GLOBALS['comment'] = $comment;
520         switch ( $comment->comment_type ) :
521                 case 'pingback' :
522                 case 'trackback' :
523         ?>
524         <li class="post pingback">
525                 <p><?php _e( 'Pingback:', 'twentyeleven' ); ?> <?php comment_author_link(); ?><?php edit_comment_link( __( 'Edit', 'twentyeleven' ), '<span class="edit-link">', '</span>' ); ?></p>
526         <?php
527                         break;
528                 default :
529         ?>
530         <li <?php comment_class(); ?> id="li-comment-<?php comment_ID(); ?>">
531                 <article id="comment-<?php comment_ID(); ?>" class="comment">
532                         <footer class="comment-meta">
533                                 <div class="comment-author vcard">
534                                         <?php
535                                                 $avatar_size = 68;
536                                                 if ( '0' != $comment->comment_parent )
537                                                         $avatar_size = 39;
538
539                                                 echo get_avatar( $comment, $avatar_size );
540
541                                                 /* translators: 1: comment author, 2: date and time */
542                                                 printf( __( '%1$s on %2$s <span class="says">said:</span>', 'twentyeleven' ),
543                                                         sprintf( '<span class="fn">%s</span>', get_comment_author_link() ),
544                                                         sprintf( '<a href="%1$s"><time datetime="%2$s">%3$s</time></a>',
545                                                                 esc_url( get_comment_link( $comment->comment_ID ) ),
546                                                                 get_comment_time( 'c' ),
547                                                                 /* translators: 1: date, 2: time */
548                                                                 sprintf( __( '%1$s at %2$s', 'twentyeleven' ), get_comment_date(), get_comment_time() )
549                                                         )
550                                                 );
551                                         ?>
552
553                                         <?php edit_comment_link( __( 'Edit', 'twentyeleven' ), '<span class="edit-link">', '</span>' ); ?>
554                                 </div><!-- .comment-author .vcard -->
555
556                                 <?php if ( $comment->comment_approved == '0' ) : ?>
557                                         <em class="comment-awaiting-moderation"><?php _e( 'Your comment is awaiting moderation.', 'twentyeleven' ); ?></em>
558                                         <br />
559                                 <?php endif; ?>
560
561                         </footer>
562
563                         <div class="comment-content"><?php comment_text(); ?></div>
564
565                         <div class="reply">
566                                 <?php comment_reply_link( array_merge( $args, array( 'reply_text' => __( 'Reply <span>&darr;</span>', 'twentyeleven' ), 'depth' => $depth, 'max_depth' => $args['max_depth'] ) ) ); ?>
567                         </div><!-- .reply -->
568                 </article><!-- #comment-## -->
569
570         <?php
571                         break;
572         endswitch;
573 }
574 endif; // ends check for twentyeleven_comment()
575
576 if ( ! function_exists( 'twentyeleven_posted_on' ) ) :
577 /**
578  * Prints HTML with meta information for the current post-date/time and author.
579  * Create your own twentyeleven_posted_on to override in a child theme
580  *
581  * @since Twenty Eleven 1.0
582  */
583 function twentyeleven_posted_on() {
584         printf( __( '<span class="sep">Posted on </span><a href="%1$s" title="%2$s" rel="bookmark"><time class="entry-date" datetime="%3$s">%4$s</time></a><span class="by-author"> <span class="sep"> by </span> <span class="author vcard"><a class="url fn n" href="%5$s" title="%6$s" rel="author">%7$s</a></span></span>', 'twentyeleven' ),
585                 esc_url( get_permalink() ),
586                 esc_attr( get_the_time() ),
587                 esc_attr( get_the_date( 'c' ) ),
588                 esc_html( get_the_date() ),
589                 esc_url( get_author_posts_url( get_the_author_meta( 'ID' ) ) ),
590                 esc_attr( sprintf( __( 'View all posts by %s', 'twentyeleven' ), get_the_author() ) ),
591                 get_the_author()
592         );
593 }
594 endif;
595
596 /**
597  * Adds two classes to the array of body classes.
598  * The first is if the site has only had one author with published posts.
599  * The second is if a singular post being displayed
600  *
601  * @since Twenty Eleven 1.0
602  */
603 function twentyeleven_body_classes( $classes ) {
604
605         if ( function_exists( 'is_multi_author' ) && ! is_multi_author() )
606                 $classes[] = 'single-author';
607
608         if ( is_singular() && ! is_home() && ! is_page_template( 'showcase.php' ) && ! is_page_template( 'sidebar-page.php' ) )
609                 $classes[] = 'singular';
610
611         return $classes;
612 }
613 add_filter( 'body_class', 'twentyeleven_body_classes' );
614