web/wp-content/themes/twentyten/functions.php
changeset 194 32102edaa81b
child 204 09a1c134465b
equal deleted inserted replaced
193:2f6f6f7551ca 194:32102edaa81b
       
     1 <?php
       
     2 /**
       
     3  * TwentyTen 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, twentyten_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', 'twentyten_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_Ten
       
    38  * @since Twenty Ten 1.0
       
    39  */
       
    40 
       
    41 /**
       
    42  * Set the content width based on the theme's design and stylesheet.
       
    43  *
       
    44  * Used to set the width of images and content. Should be equal to the width the theme
       
    45  * is designed for, generally via the style.css stylesheet.
       
    46  */
       
    47 if ( ! isset( $content_width ) )
       
    48 	$content_width = 640;
       
    49 
       
    50 /** Tell WordPress to run twentyten_setup() when the 'after_setup_theme' hook is run. */
       
    51 add_action( 'after_setup_theme', 'twentyten_setup' );
       
    52 
       
    53 if ( ! function_exists( 'twentyten_setup' ) ):
       
    54 /**
       
    55  * Sets up theme defaults and registers support for various WordPress features.
       
    56  *
       
    57  * Note that this function is hooked into the after_setup_theme hook, which runs
       
    58  * before the init hook. The init hook is too late for some features, such as indicating
       
    59  * support post thumbnails.
       
    60  *
       
    61  * To override twentyten_setup() in a child theme, add your own twentyten_setup to your child theme's
       
    62  * functions.php file.
       
    63  *
       
    64  * @uses add_theme_support() To add support for post thumbnails, custom headers and backgrounds, and automatic feed links.
       
    65  * @uses register_nav_menus() To add support for navigation menus.
       
    66  * @uses add_editor_style() To style the visual editor.
       
    67  * @uses load_theme_textdomain() For translation/localization support.
       
    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 Ten 1.0
       
    72  */
       
    73 function twentyten_setup() {
       
    74 
       
    75 	// This theme styles the visual editor with editor-style.css to match the theme style.
       
    76 	add_editor_style();
       
    77 
       
    78 	// Post Format support. You can also use the legacy "gallery" or "asides" (note the plural) categories.
       
    79 	add_theme_support( 'post-formats', array( 'aside', 'gallery' ) );
       
    80 
       
    81 	// This theme uses post thumbnails
       
    82 	add_theme_support( 'post-thumbnails' );
       
    83 
       
    84 	// Add default posts and comments RSS feed links to head
       
    85 	add_theme_support( 'automatic-feed-links' );
       
    86 
       
    87 	// Make theme available for translation
       
    88 	// Translations can be filed in the /languages/ directory
       
    89 	load_theme_textdomain( 'twentyten', get_template_directory() . '/languages' );
       
    90 
       
    91 	// This theme uses wp_nav_menu() in one location.
       
    92 	register_nav_menus( array(
       
    93 		'primary' => __( 'Primary Navigation', 'twentyten' ),
       
    94 	) );
       
    95 
       
    96 	// This theme allows users to set a custom background.
       
    97 	add_theme_support( 'custom-background', array(
       
    98 		// Let WordPress know what our default background color is.
       
    99 		'default-color' => 'f1f1f1',
       
   100 	) );
       
   101 
       
   102 	// The custom header business starts here.
       
   103 
       
   104 	$custom_header_support = array(
       
   105 		// The default image to use.
       
   106 		// The %s is a placeholder for the theme template directory URI.
       
   107 		'default-image' => '%s/images/headers/path.jpg',
       
   108 		// The height and width of our custom header.
       
   109 		'width' => apply_filters( 'twentyten_header_image_width', 940 ),
       
   110 		'height' => apply_filters( 'twentyten_header_image_height', 198 ),
       
   111 		// Support flexible heights.
       
   112 		'flex-height' => true,
       
   113 		// Don't support text inside the header image.
       
   114 		'header-text' => false,
       
   115 		// Callback for styling the header preview in the admin.
       
   116 		'admin-head-callback' => 'twentyten_admin_header_style',
       
   117 	);
       
   118 	
       
   119 	add_theme_support( 'custom-header', $custom_header_support );
       
   120 	
       
   121 	if ( ! function_exists( 'get_custom_header' ) ) {
       
   122 		// This is all for compatibility with versions of WordPress prior to 3.4.
       
   123 		define( 'HEADER_TEXTCOLOR', '' );
       
   124 		define( 'NO_HEADER_TEXT', true );
       
   125 		define( 'HEADER_IMAGE', $custom_header_support['default-image'] );
       
   126 		define( 'HEADER_IMAGE_WIDTH', $custom_header_support['width'] );
       
   127 		define( 'HEADER_IMAGE_HEIGHT', $custom_header_support['height'] );
       
   128 		add_custom_image_header( '', $custom_header_support['admin-head-callback'] );
       
   129 		add_custom_background();
       
   130 	}
       
   131 
       
   132 	// We'll be using post thumbnails for custom header images on posts and pages.
       
   133 	// We want them to be 940 pixels wide by 198 pixels tall.
       
   134 	// Larger images will be auto-cropped to fit, smaller ones will be ignored. See header.php.
       
   135 	set_post_thumbnail_size( $custom_header_support['width'], $custom_header_support['height'], true );
       
   136 
       
   137 	// ... and thus ends the custom header business.
       
   138 
       
   139 	// Default custom headers packaged with the theme. %s is a placeholder for the theme template directory URI.
       
   140 	register_default_headers( array(
       
   141 		'berries' => array(
       
   142 			'url' => '%s/images/headers/berries.jpg',
       
   143 			'thumbnail_url' => '%s/images/headers/berries-thumbnail.jpg',
       
   144 			/* translators: header image description */
       
   145 			'description' => __( 'Berries', 'twentyten' )
       
   146 		),
       
   147 		'cherryblossom' => array(
       
   148 			'url' => '%s/images/headers/cherryblossoms.jpg',
       
   149 			'thumbnail_url' => '%s/images/headers/cherryblossoms-thumbnail.jpg',
       
   150 			/* translators: header image description */
       
   151 			'description' => __( 'Cherry Blossoms', 'twentyten' )
       
   152 		),
       
   153 		'concave' => array(
       
   154 			'url' => '%s/images/headers/concave.jpg',
       
   155 			'thumbnail_url' => '%s/images/headers/concave-thumbnail.jpg',
       
   156 			/* translators: header image description */
       
   157 			'description' => __( 'Concave', 'twentyten' )
       
   158 		),
       
   159 		'fern' => array(
       
   160 			'url' => '%s/images/headers/fern.jpg',
       
   161 			'thumbnail_url' => '%s/images/headers/fern-thumbnail.jpg',
       
   162 			/* translators: header image description */
       
   163 			'description' => __( 'Fern', 'twentyten' )
       
   164 		),
       
   165 		'forestfloor' => array(
       
   166 			'url' => '%s/images/headers/forestfloor.jpg',
       
   167 			'thumbnail_url' => '%s/images/headers/forestfloor-thumbnail.jpg',
       
   168 			/* translators: header image description */
       
   169 			'description' => __( 'Forest Floor', 'twentyten' )
       
   170 		),
       
   171 		'inkwell' => array(
       
   172 			'url' => '%s/images/headers/inkwell.jpg',
       
   173 			'thumbnail_url' => '%s/images/headers/inkwell-thumbnail.jpg',
       
   174 			/* translators: header image description */
       
   175 			'description' => __( 'Inkwell', 'twentyten' )
       
   176 		),
       
   177 		'path' => array(
       
   178 			'url' => '%s/images/headers/path.jpg',
       
   179 			'thumbnail_url' => '%s/images/headers/path-thumbnail.jpg',
       
   180 			/* translators: header image description */
       
   181 			'description' => __( 'Path', 'twentyten' )
       
   182 		),
       
   183 		'sunset' => array(
       
   184 			'url' => '%s/images/headers/sunset.jpg',
       
   185 			'thumbnail_url' => '%s/images/headers/sunset-thumbnail.jpg',
       
   186 			/* translators: header image description */
       
   187 			'description' => __( 'Sunset', 'twentyten' )
       
   188 		)
       
   189 	) );
       
   190 }
       
   191 endif;
       
   192 
       
   193 if ( ! function_exists( 'twentyten_admin_header_style' ) ) :
       
   194 /**
       
   195  * Styles the header image displayed on the Appearance > Header admin panel.
       
   196  *
       
   197  * Referenced via add_custom_image_header() in twentyten_setup().
       
   198  *
       
   199  * @since Twenty Ten 1.0
       
   200  */
       
   201 function twentyten_admin_header_style() {
       
   202 ?>
       
   203 <style type="text/css">
       
   204 /* Shows the same border as on front end */
       
   205 #headimg {
       
   206 	border-bottom: 1px solid #000;
       
   207 	border-top: 4px solid #000;
       
   208 }
       
   209 /* If header-text was supported, you would style the text with these selectors:
       
   210 	#headimg #name { }
       
   211 	#headimg #desc { }
       
   212 */
       
   213 </style>
       
   214 <?php
       
   215 }
       
   216 endif;
       
   217 
       
   218 /**
       
   219  * Get our wp_nav_menu() fallback, wp_page_menu(), to show a home link.
       
   220  *
       
   221  * To override this in a child theme, remove the filter and optionally add
       
   222  * your own function tied to the wp_page_menu_args filter hook.
       
   223  *
       
   224  * @since Twenty Ten 1.0
       
   225  */
       
   226 function twentyten_page_menu_args( $args ) {
       
   227 	$args['show_home'] = true;
       
   228 	return $args;
       
   229 }
       
   230 add_filter( 'wp_page_menu_args', 'twentyten_page_menu_args' );
       
   231 
       
   232 /**
       
   233  * Sets the post excerpt length to 40 characters.
       
   234  *
       
   235  * To override this length in a child theme, remove the filter and add your own
       
   236  * function tied to the excerpt_length filter hook.
       
   237  *
       
   238  * @since Twenty Ten 1.0
       
   239  * @return int
       
   240  */
       
   241 function twentyten_excerpt_length( $length ) {
       
   242 	return 40;
       
   243 }
       
   244 add_filter( 'excerpt_length', 'twentyten_excerpt_length' );
       
   245 
       
   246 /**
       
   247  * Returns a "Continue Reading" link for excerpts
       
   248  *
       
   249  * @since Twenty Ten 1.0
       
   250  * @return string "Continue Reading" link
       
   251  */
       
   252 function twentyten_continue_reading_link() {
       
   253 	return ' <a href="'. get_permalink() . '">' . __( 'Continue reading <span class="meta-nav">&rarr;</span>', 'twentyten' ) . '</a>';
       
   254 }
       
   255 
       
   256 /**
       
   257  * Replaces "[...]" (appended to automatically generated excerpts) with an ellipsis and twentyten_continue_reading_link().
       
   258  *
       
   259  * To override this in a child theme, remove the filter and add your own
       
   260  * function tied to the excerpt_more filter hook.
       
   261  *
       
   262  * @since Twenty Ten 1.0
       
   263  * @return string An ellipsis
       
   264  */
       
   265 function twentyten_auto_excerpt_more( $more ) {
       
   266 	return ' &hellip;' . twentyten_continue_reading_link();
       
   267 }
       
   268 add_filter( 'excerpt_more', 'twentyten_auto_excerpt_more' );
       
   269 
       
   270 /**
       
   271  * Adds a pretty "Continue Reading" link to custom post excerpts.
       
   272  *
       
   273  * To override this link in a child theme, remove the filter and add your own
       
   274  * function tied to the get_the_excerpt filter hook.
       
   275  *
       
   276  * @since Twenty Ten 1.0
       
   277  * @return string Excerpt with a pretty "Continue Reading" link
       
   278  */
       
   279 function twentyten_custom_excerpt_more( $output ) {
       
   280 	if ( has_excerpt() && ! is_attachment() ) {
       
   281 		$output .= twentyten_continue_reading_link();
       
   282 	}
       
   283 	return $output;
       
   284 }
       
   285 add_filter( 'get_the_excerpt', 'twentyten_custom_excerpt_more' );
       
   286 
       
   287 /**
       
   288  * Remove inline styles printed when the gallery shortcode is used.
       
   289  *
       
   290  * Galleries are styled by the theme in Twenty Ten's style.css. This is just
       
   291  * a simple filter call that tells WordPress to not use the default styles.
       
   292  *
       
   293  * @since Twenty Ten 1.2
       
   294  */
       
   295 add_filter( 'use_default_gallery_style', '__return_false' );
       
   296 
       
   297 /**
       
   298  * Deprecated way to remove inline styles printed when the gallery shortcode is used.
       
   299  *
       
   300  * This function is no longer needed or used. Use the use_default_gallery_style
       
   301  * filter instead, as seen above.
       
   302  *
       
   303  * @since Twenty Ten 1.0
       
   304  * @deprecated Deprecated in Twenty Ten 1.2 for WordPress 3.1
       
   305  *
       
   306  * @return string The gallery style filter, with the styles themselves removed.
       
   307  */
       
   308 function twentyten_remove_gallery_css( $css ) {
       
   309 	return preg_replace( "#<style type='text/css'>(.*?)</style>#s", '', $css );
       
   310 }
       
   311 // Backwards compatibility with WordPress 3.0.
       
   312 if ( version_compare( $GLOBALS['wp_version'], '3.1', '<' ) )
       
   313 	add_filter( 'gallery_style', 'twentyten_remove_gallery_css' );
       
   314 
       
   315 if ( ! function_exists( 'twentyten_comment' ) ) :
       
   316 /**
       
   317  * Template for comments and pingbacks.
       
   318  *
       
   319  * To override this walker in a child theme without modifying the comments template
       
   320  * simply create your own twentyten_comment(), and that function will be used instead.
       
   321  *
       
   322  * Used as a callback by wp_list_comments() for displaying the comments.
       
   323  *
       
   324  * @since Twenty Ten 1.0
       
   325  */
       
   326 function twentyten_comment( $comment, $args, $depth ) {
       
   327 	$GLOBALS['comment'] = $comment;
       
   328 	switch ( $comment->comment_type ) :
       
   329 		case '' :
       
   330 	?>
       
   331 	<li <?php comment_class(); ?> id="li-comment-<?php comment_ID(); ?>">
       
   332 		<div id="comment-<?php comment_ID(); ?>">
       
   333 		<div class="comment-author vcard">
       
   334 			<?php echo get_avatar( $comment, 40 ); ?>
       
   335 			<?php printf( __( '%s <span class="says">says:</span>', 'twentyten' ), sprintf( '<cite class="fn">%s</cite>', get_comment_author_link() ) ); ?>
       
   336 		</div><!-- .comment-author .vcard -->
       
   337 		<?php if ( $comment->comment_approved == '0' ) : ?>
       
   338 			<em class="comment-awaiting-moderation"><?php _e( 'Your comment is awaiting moderation.', 'twentyten' ); ?></em>
       
   339 			<br />
       
   340 		<?php endif; ?>
       
   341 
       
   342 		<div class="comment-meta commentmetadata"><a href="<?php echo esc_url( get_comment_link( $comment->comment_ID ) ); ?>">
       
   343 			<?php
       
   344 				/* translators: 1: date, 2: time */
       
   345 				printf( __( '%1$s at %2$s', 'twentyten' ), get_comment_date(),  get_comment_time() ); ?></a><?php edit_comment_link( __( '(Edit)', 'twentyten' ), ' ' );
       
   346 			?>
       
   347 		</div><!-- .comment-meta .commentmetadata -->
       
   348 
       
   349 		<div class="comment-body"><?php comment_text(); ?></div>
       
   350 
       
   351 		<div class="reply">
       
   352 			<?php comment_reply_link( array_merge( $args, array( 'depth' => $depth, 'max_depth' => $args['max_depth'] ) ) ); ?>
       
   353 		</div><!-- .reply -->
       
   354 	</div><!-- #comment-##  -->
       
   355 
       
   356 	<?php
       
   357 			break;
       
   358 		case 'pingback'  :
       
   359 		case 'trackback' :
       
   360 	?>
       
   361 	<li class="post pingback">
       
   362 		<p><?php _e( 'Pingback:', 'twentyten' ); ?> <?php comment_author_link(); ?><?php edit_comment_link( __( '(Edit)', 'twentyten' ), ' ' ); ?></p>
       
   363 	<?php
       
   364 			break;
       
   365 	endswitch;
       
   366 }
       
   367 endif;
       
   368 
       
   369 /**
       
   370  * Register widgetized areas, including two sidebars and four widget-ready columns in the footer.
       
   371  *
       
   372  * To override twentyten_widgets_init() in a child theme, remove the action hook and add your own
       
   373  * function tied to the init hook.
       
   374  *
       
   375  * @since Twenty Ten 1.0
       
   376  * @uses register_sidebar
       
   377  */
       
   378 function twentyten_widgets_init() {
       
   379 	// Area 1, located at the top of the sidebar.
       
   380 	register_sidebar( array(
       
   381 		'name' => __( 'Primary Widget Area', 'twentyten' ),
       
   382 		'id' => 'primary-widget-area',
       
   383 		'description' => __( 'The primary widget area', 'twentyten' ),
       
   384 		'before_widget' => '<li id="%1$s" class="widget-container %2$s">',
       
   385 		'after_widget' => '</li>',
       
   386 		'before_title' => '<h3 class="widget-title">',
       
   387 		'after_title' => '</h3>',
       
   388 	) );
       
   389 
       
   390 	// Area 2, located below the Primary Widget Area in the sidebar. Empty by default.
       
   391 	register_sidebar( array(
       
   392 		'name' => __( 'Secondary Widget Area', 'twentyten' ),
       
   393 		'id' => 'secondary-widget-area',
       
   394 		'description' => __( 'The secondary widget area', 'twentyten' ),
       
   395 		'before_widget' => '<li id="%1$s" class="widget-container %2$s">',
       
   396 		'after_widget' => '</li>',
       
   397 		'before_title' => '<h3 class="widget-title">',
       
   398 		'after_title' => '</h3>',
       
   399 	) );
       
   400 
       
   401 	// Area 3, located in the footer. Empty by default.
       
   402 	register_sidebar( array(
       
   403 		'name' => __( 'First Footer Widget Area', 'twentyten' ),
       
   404 		'id' => 'first-footer-widget-area',
       
   405 		'description' => __( 'The first footer widget area', 'twentyten' ),
       
   406 		'before_widget' => '<li id="%1$s" class="widget-container %2$s">',
       
   407 		'after_widget' => '</li>',
       
   408 		'before_title' => '<h3 class="widget-title">',
       
   409 		'after_title' => '</h3>',
       
   410 	) );
       
   411 
       
   412 	// Area 4, located in the footer. Empty by default.
       
   413 	register_sidebar( array(
       
   414 		'name' => __( 'Second Footer Widget Area', 'twentyten' ),
       
   415 		'id' => 'second-footer-widget-area',
       
   416 		'description' => __( 'The second footer widget area', 'twentyten' ),
       
   417 		'before_widget' => '<li id="%1$s" class="widget-container %2$s">',
       
   418 		'after_widget' => '</li>',
       
   419 		'before_title' => '<h3 class="widget-title">',
       
   420 		'after_title' => '</h3>',
       
   421 	) );
       
   422 
       
   423 	// Area 5, located in the footer. Empty by default.
       
   424 	register_sidebar( array(
       
   425 		'name' => __( 'Third Footer Widget Area', 'twentyten' ),
       
   426 		'id' => 'third-footer-widget-area',
       
   427 		'description' => __( 'The third footer widget area', 'twentyten' ),
       
   428 		'before_widget' => '<li id="%1$s" class="widget-container %2$s">',
       
   429 		'after_widget' => '</li>',
       
   430 		'before_title' => '<h3 class="widget-title">',
       
   431 		'after_title' => '</h3>',
       
   432 	) );
       
   433 
       
   434 	// Area 6, located in the footer. Empty by default.
       
   435 	register_sidebar( array(
       
   436 		'name' => __( 'Fourth Footer Widget Area', 'twentyten' ),
       
   437 		'id' => 'fourth-footer-widget-area',
       
   438 		'description' => __( 'The fourth footer widget area', 'twentyten' ),
       
   439 		'before_widget' => '<li id="%1$s" class="widget-container %2$s">',
       
   440 		'after_widget' => '</li>',
       
   441 		'before_title' => '<h3 class="widget-title">',
       
   442 		'after_title' => '</h3>',
       
   443 	) );
       
   444 }
       
   445 /** Register sidebars by running twentyten_widgets_init() on the widgets_init hook. */
       
   446 add_action( 'widgets_init', 'twentyten_widgets_init' );
       
   447 
       
   448 /**
       
   449  * Removes the default styles that are packaged with the Recent Comments widget.
       
   450  *
       
   451  * To override this in a child theme, remove the filter and optionally add your own
       
   452  * function tied to the widgets_init action hook.
       
   453  *
       
   454  * This function uses a filter (show_recent_comments_widget_style) new in WordPress 3.1
       
   455  * to remove the default style. Using Twenty Ten 1.2 in WordPress 3.0 will show the styles,
       
   456  * but they won't have any effect on the widget in default Twenty Ten styling.
       
   457  *
       
   458  * @since Twenty Ten 1.0
       
   459  */
       
   460 function twentyten_remove_recent_comments_style() {
       
   461 	add_filter( 'show_recent_comments_widget_style', '__return_false' );
       
   462 }
       
   463 add_action( 'widgets_init', 'twentyten_remove_recent_comments_style' );
       
   464 
       
   465 if ( ! function_exists( 'twentyten_posted_on' ) ) :
       
   466 /**
       
   467  * Prints HTML with meta information for the current post-date/time and author.
       
   468  *
       
   469  * @since Twenty Ten 1.0
       
   470  */
       
   471 function twentyten_posted_on() {
       
   472 	printf( __( '<span class="%1$s">Posted on</span> %2$s <span class="meta-sep">by</span> %3$s', 'twentyten' ),
       
   473 		'meta-prep meta-prep-author',
       
   474 		sprintf( '<a href="%1$s" title="%2$s" rel="bookmark"><span class="entry-date">%3$s</span></a>',
       
   475 			get_permalink(),
       
   476 			esc_attr( get_the_time() ),
       
   477 			get_the_date()
       
   478 		),
       
   479 		sprintf( '<span class="author vcard"><a class="url fn n" href="%1$s" title="%2$s">%3$s</a></span>',
       
   480 			get_author_posts_url( get_the_author_meta( 'ID' ) ),
       
   481 			esc_attr( sprintf( __( 'View all posts by %s', 'twentyten' ), get_the_author() ) ),
       
   482 			get_the_author()
       
   483 		)
       
   484 	);
       
   485 }
       
   486 endif;
       
   487 
       
   488 if ( ! function_exists( 'twentyten_posted_in' ) ) :
       
   489 /**
       
   490  * Prints HTML with meta information for the current post (category, tags and permalink).
       
   491  *
       
   492  * @since Twenty Ten 1.0
       
   493  */
       
   494 function twentyten_posted_in() {
       
   495 	// Retrieves tag list of current post, separated by commas.
       
   496 	$tag_list = get_the_tag_list( '', ', ' );
       
   497 	if ( $tag_list ) {
       
   498 		$posted_in = __( 'This entry was posted in %1$s and tagged %2$s. Bookmark the <a href="%3$s" title="Permalink to %4$s" rel="bookmark">permalink</a>.', 'twentyten' );
       
   499 	} elseif ( is_object_in_taxonomy( get_post_type(), 'category' ) ) {
       
   500 		$posted_in = __( 'This entry was posted in %1$s. Bookmark the <a href="%3$s" title="Permalink to %4$s" rel="bookmark">permalink</a>.', 'twentyten' );
       
   501 	} else {
       
   502 		$posted_in = __( 'Bookmark the <a href="%3$s" title="Permalink to %4$s" rel="bookmark">permalink</a>.', 'twentyten' );
       
   503 	}
       
   504 	// Prints the string, replacing the placeholders.
       
   505 	printf(
       
   506 		$posted_in,
       
   507 		get_the_category_list( ', ' ),
       
   508 		$tag_list,
       
   509 		get_permalink(),
       
   510 		the_title_attribute( 'echo=0' )
       
   511 	);
       
   512 }
       
   513 endif;