* @copyright Copyright (c) 2010 - 2012, Justin Tadlock * @link http://justintadlock.com * @license http://www.gnu.org/licenses/old-licenses/gpl-2.0.html */ /* Register metadata with WordPress. */ add_action( 'init', 'theme_layouts_register_meta' ); /* Add post type support for theme layouts. */ add_action( 'init', 'theme_layouts_add_post_type_support' ); add_action( 'init', 'theme_layouts_remove_post_type_support' ); /* Set up the custom post layouts. */ add_action( 'admin_menu', 'theme_layouts_admin_setup' ); /* Filters the body_class hook to add a custom class. */ add_filter( 'body_class', 'theme_layouts_body_class' ); /** * Registers the theme layouts meta key ('Layout') for specific object types and provides a function to sanitize * the metadata on update. * * @since 0.4.0 * @return void */ function theme_layouts_register_meta() { register_meta( 'post', theme_layouts_get_meta_key(), 'theme_layouts_sanitize_meta' ); register_meta( 'user', theme_layouts_get_meta_key(), 'theme_layouts_sanitize_meta' ); } /** * Callback function for sanitizing meta when add_metadata() or update_metadata() is called by WordPress. * If a developer wants to set up a custom method for sanitizing the data, they should use the * "sanitize_{$meta_type}_meta_{$meta_key}" filter hook to do so. * * @since 0.4.0 * @param mixed $meta_value The value of the data to sanitize. * @param string $meta_key The meta key name. * @param string $meta_type The type of metadata (post, comment, user, etc.) * @return mixed $meta_value */ function theme_layouts_sanitize_meta( $meta_value, $meta_key, $meta_type ) { return esc_attr( strip_tags( $meta_value ) ); } /** * Adds post type support to all 'public' post types. This allows themes to remove support for the 'theme-layouts' * feature with remove_post_type_support(). * * @since 0.4.0 * @return void */ function theme_layouts_add_post_type_support() { /* Gets available public post types. */ $post_types = get_post_types( array( 'public' => true ) ); /* For each available post type, create a meta box on its edit page if it supports '$prefix-post-settings'. */ foreach ( $post_types as $type ) add_post_type_support( $type, 'theme-layouts' ); } /** * Removes theme layouts support from specific post types created by plugins. * * @since 0.4.0 * @return void */ function theme_layouts_remove_post_type_support() { /* Removes theme layouts support of the bbPress 'reply' post type. */ if ( function_exists( 'bbp_get_reply_post_type' ) ) remove_post_type_support( bbp_get_reply_post_type(), 'theme-layouts' ); } /** * Gets the layout for the current post based off the 'Layout' custom field key if viewing a singular post * entry. All other pages are given a default layout of 'layout-default'. * * @since 0.2.0 * @return string The layout for the given page. */ function theme_layouts_get_layout() { /* Get the available post layouts. */ $post_layouts = get_theme_support( 'theme-layouts' ); /* Set the layout to an empty string. */ $layout = ''; /* If viewing a singular post, check if a layout has been specified. */ if ( is_singular() ) { /* Get the current post ID. */ $post_id = get_queried_object_id(); /* Get the post layout. */ $layout = get_post_layout( $post_id ); } /* If viewing a user/author archive, check if a layout has been specified. */ elseif ( is_author() ) { /* Get the current user ID. */ $user_id = get_queried_object_id(); /* Get the user layout. */ $layout = get_user_layout( $user_id ); } /* Make sure the given layout is in the array of available post layouts for the theme. */ if ( empty( $layout ) || !in_array( $layout, $post_layouts[0] ) ) $layout = 'default'; /* If the theme set a default layout, use it if the layout should be set to default. */ if ( 'default' == $layout && !empty( $post_layouts[1] ) && isset( $post_layouts[1]['default'] ) ) $layout = $post_layouts[1]['default']; /* @deprecated 0.2.0. Use the 'get_theme_layout' hook. */ $layout = apply_filters( 'get_post_layout', "layout-{$layout}" ); /* Return the layout and allow plugin/theme developers to override it. */ return esc_attr( apply_filters( 'get_theme_layout', $layout ) ); } /** * Get the post layout based on the given post ID. * * @since 0.2.0 * @param int $post_id The ID of the post to get the layout for. * @return string $layout The name of the post's layout. */ function get_post_layout( $post_id ) { /* Get the post layout. */ $layout = get_post_meta( $post_id, theme_layouts_get_meta_key(), true ); /* Return the layout if one is found. Otherwise, return 'default'. */ return ( !empty( $layout ) ? $layout : 'default' ); } /** * Update/set the post layout based on the given post ID and layout. * * @since 0.2.0 * @param int $post_id The ID of the post to set the layout for. * @param string $layout The name of the layout to set. * @return bool True on successful update, false on failure. */ function set_post_layout( $post_id, $layout ) { return update_post_meta( $post_id, theme_layouts_get_meta_key(), $layout ); } /** * Deletes a post layout. * * @since 0.4.0 * @access public * @param int $post_id The ID of the post to delete the layout for. * @return bool True on successful delete, false on failure. */ function delete_post_layout( $post_id ) { return delete_post_meta( $post_id, theme_layouts_get_meta_key() ); } /** * Checks if a specific post's layout matches that of the given layout. * * @since 0.3.0 * @param string $layout The name of the layout to check if the post has. * @param int $post_id The ID of the post to check the layout for. * @return bool Whether the given layout matches the post's layout. */ function has_post_layout( $layout, $post_id = '' ) { /* If no post ID is given, use WP's get_the_ID() to get it and assume we're in the post loop. */ if ( empty( $post_id ) ) $post_id = get_the_ID(); /* Return true/false based on whether the layout matches. */ return ( $layout == get_post_layout( $post_id ) ? true : false ); } /** * Get the layout for a user/author archive page based on a specific user ID. * * @since 0.3.0 * @param int $user_id The ID of the user to get the layout for. * @return string The layout if one exists, 'default' if one doesn't. */ function get_user_layout( $user_id ) { /* Get the user layout. */ $layout = get_user_meta( $user_id, theme_layouts_get_meta_key(), true ); /* Return the layout if one is found. Otherwise, return 'default'. */ return ( !empty( $layout ) ? $layout : 'default' ); } /** * Update/set the layout for a user/author archive paged based on the user ID. * * @since 0.3.0 * @param int $user_id The ID of the user to set the layout for. * @param string $layout The name of the layout to set. * @return bool True on successful update, false on failure. */ function set_user_layout( $user_id, $layout ) { return update_user_meta( $user_id, theme_layouts_get_meta_key(), $layout ); } /** * Deletes a user layout. * * @since 0.4.0 * @access public * @param int $user_id The ID of the user to delete the layout for. * @return bool True on successful delete, false on failure. */ function delete_user_layout( $user_id ) { return delete_user_meta( $user_id, theme_layouts_get_meta_key() ); } /** * Checks if a specific user's layout matches that of the given layout. * * @since 0.3.0 * @param string $layout The name of the layout to check if the user has. * @param int $user_id The ID of the user to check the layout for. * @return bool Whether the given layout matches the user's layout. */ function has_user_layout( $layout, $user_id = '' ) { /* If no user ID is given, assume we're viewing an author archive page and get the user ID. */ if ( empty( $user_id ) ) $user_id = get_query_var( 'author' ); /* Return true/false based on whether the layout matches. */ return ( $layout == get_user_layout( $user_id ) ? true : false ); } /** * Adds the post layout class to the WordPress body class in the form of "layout-$layout". This allows * theme developers to design their theme layouts based on the layout class. If designing a theme with * this extension, the theme should make sure to handle all possible layout classes. * * @since 0.2.0 * @param array $classes * @param array $classes */ function theme_layouts_body_class( $classes ) { /* Adds the layout to array of body classes. */ $classes[] = sanitize_html_class( theme_layouts_get_layout() ); /* Return the $classes array. */ return $classes; } /** * Creates default text strings based on the default post layouts. Theme developers that add custom * layouts should filter 'post_layouts_strings' to add strings to match the custom layouts, but it's not * required. The layout name will be used if no text string is found. * * @since 0.2.0 * @return array $strings */ function theme_layouts_strings() { /* Set up the default layout strings. */ $strings = array( 'default' => __( 'Default', 'theme-layouts' ), '1c' => __( 'One Column', 'theme-layouts' ), '2c-l' => __( 'Two Columns, Left', 'theme-layouts' ), '2c-r' => __( 'Two Columns, Right', 'theme-layouts' ), '3c-l' => __( 'Three Columns, Left', 'theme-layouts' ), '3c-r' => __( 'Three Columns, Right', 'theme-layouts' ), '3c-c' => __( 'Three Columns, Center', 'theme-layouts' ) ); /* Allow devs to filter the strings for custom layouts. */ return apply_filters( 'theme_layouts_strings', $strings ); } /** * Get a specific layout's text string. * * @since 0.2.0 * @param string $layout * @return string */ function theme_layouts_get_string( $layout ) { /* Get an array of post layout strings. */ $strings = theme_layouts_strings(); /* Return the layout's string if it exists. Else, return the layout slug. */ return ( ( isset( $strings[$layout] ) ) ? $strings[$layout] : $layout ); } /** * Post layouts admin setup. Registers the post layouts meta box for the post editing screen. Adds the * metadata save function to the 'save_post' hook. * * @since 0.2.0 * @return void */ function theme_layouts_admin_setup() { /* Load the post meta boxes on the new post and edit post screens. */ add_action( 'load-post.php', 'theme_layouts_load_meta_boxes' ); add_action( 'load-post-new.php', 'theme_layouts_load_meta_boxes' ); /* If the attachment post type supports 'theme-layouts', add form fields for it. */ if ( post_type_supports( 'attachment', 'theme-layouts' ) ) { /* Adds a theme layout />
  • />
  • ID ); /* Set the default post layout. */ $select = ''; /* Loop through each theme-supported layout, adding it to the select element. */ foreach ( $post_layouts as $layout ) $select .= ''; /* Set the HTML for the post layout select drop-down. */ $select = ''; /* Add the attachment layout field to the $fields array. */ $fields['theme-layouts-post-layout'] = array( 'label' => __( 'Layout', 'theme-layouts' ), 'input' => 'html', 'html' => $select ); /* Return the $fields array back to WordPress. */ return $fields; } /** * Saves the attachment layout for the attachment edit form. * * @since 0.3.0 * @access private * @param array $post The attachment post array (not the post object!). * @param array $fields Array of fields for the edit attachment form. * @return array $post */ function theme_layouts_attachment_fields_to_save( $post, $fields ) { /* If the theme layouts field was submitted. */ if ( isset( $fields['theme-layouts-post-layout'] ) ) { /* Get the meta key. */ $meta_key = theme_layouts_get_meta_key(); /* Get the previous post layout. */ $meta_value = get_post_layout( $post['ID'] ); /* Get the submitted post layout. */ $new_meta_value = $fields['theme-layouts-post-layout']; /* If there is no new meta value but an old value exists, delete it. */ if ( current_user_can( 'delete_post_meta', $post['ID'], $meta_key ) && '' == $new_meta_value && $meta_value ) delete_post_layout( $post['ID'] ); /* If a new meta value was added and there was no previous value, add it. */ elseif ( current_user_can( 'add_post_meta', $post['ID'], $meta_key ) && $new_meta_value && '' == $meta_value ) set_post_layout( $post['ID'], $new_meta_value ); /* If the old layout doesn't match the new layout, update the post layout meta. */ elseif ( current_user_can( 'edit_post_meta', $post['ID'], $meta_key ) && $meta_value !== $new_meta_value ) set_post_layout( $post['ID'], $new_meta_value ); } /* Return the attachment post array. */ return $post; } /** * Wrapper function for returning the metadata key used for objects that can use layouts. * * @since 0.3.0 * @access public * @return string The meta key used for theme layouts. */ function theme_layouts_get_meta_key() { return apply_filters( 'theme_layouts_meta_key', 'Layout' ); } /** * @since 0.1.0 * @deprecated 0.2.0 Use theme_layouts_get_layout(). */ function post_layouts_get_layout() { return theme_layouts_get_layout(); } ?>