Initial commit. State 04.2021.

This commit is contained in:
2021-04-22 17:57:16 +02:00
commit 82781cca41
2974 changed files with 975656 additions and 0 deletions

View File

@@ -0,0 +1,63 @@
<?php
/**
* Twenty Fourteen back compat functionality
*
* Prevents Twenty Fourteen from running on WordPress versions prior to 3.6,
* since this theme is not meant to be backward compatible beyond that
* and relies on many newer functions and markup changes introduced in 3.6.
*
* @package WordPress
* @subpackage Twenty_Fourteen
* @since Twenty Fourteen 1.0
*/
/**
* Prevent switching to Twenty Fourteen on old versions of WordPress.
*
* Switches to the default theme.
*
* @since Twenty Fourteen 1.0
*/
function twentyfourteen_switch_theme() {
switch_theme( WP_DEFAULT_THEME, WP_DEFAULT_THEME );
unset( $_GET['activated'] );
add_action( 'admin_notices', 'twentyfourteen_upgrade_notice' );
}
add_action( 'after_switch_theme', 'twentyfourteen_switch_theme' );
/**
* Add message for unsuccessful theme switch.
*
* Prints an update nag after an unsuccessful attempt to switch to
* Twenty Fourteen on WordPress versions prior to 3.6.
*
* @since Twenty Fourteen 1.0
*/
function twentyfourteen_upgrade_notice() {
$message = sprintf( __( 'Twenty Fourteen requires at least WordPress version 3.6. You are running version %s. Please upgrade and try again.', 'twentyfourteen' ), $GLOBALS['wp_version'] );
printf( '<div class="error"><p>%s</p></div>', $message );
}
/**
* Prevent the Customizer from being loaded on WordPress versions prior to 3.6.
*
* @since Twenty Fourteen 1.0
*/
function twentyfourteen_customize() {
wp_die( sprintf( __( 'Twenty Fourteen requires at least WordPress version 3.6. You are running version %s. Please upgrade and try again.', 'twentyfourteen' ), $GLOBALS['wp_version'] ), '', array(
'back_link' => true,
) );
}
add_action( 'load-customize.php', 'twentyfourteen_customize' );
/**
* Prevent the Theme Preview from being loaded on WordPress versions prior to 3.4.
*
* @since Twenty Fourteen 1.0
*/
function twentyfourteen_preview() {
if ( isset( $_GET['preview'] ) ) {
wp_die( sprintf( __( 'Twenty Fourteen requires at least WordPress version 3.6. You are running version %s. Please upgrade and try again.', 'twentyfourteen' ), $GLOBALS['wp_version'] ) );
}
}
add_action( 'template_redirect', 'twentyfourteen_preview' );

View File

@@ -0,0 +1,147 @@
<?php
/**
* Implement Custom Header functionality for Twenty Fourteen
*
* @package WordPress
* @subpackage Twenty_Fourteen
* @since Twenty Fourteen 1.0
*/
/**
* Set up the WordPress core custom header settings.
*
* @since Twenty Fourteen 1.0
*
* @uses twentyfourteen_header_style()
* @uses twentyfourteen_admin_header_style()
* @uses twentyfourteen_admin_header_image()
*/
function twentyfourteen_custom_header_setup() {
/**
* Filter Twenty Fourteen custom-header support arguments.
*
* @since Twenty Fourteen 1.0
*
* @param array $args {
* An array of custom-header support arguments.
*
* @type bool $header_text Whether to display custom header text. Default false.
* @type int $width Width in pixels of the custom header image. Default 1260.
* @type int $height Height in pixels of the custom header image. Default 240.
* @type bool $flex_height Whether to allow flexible-height header images. Default true.
* @type string $admin_head_callback Callback function used to style the image displayed in
* the Appearance > Header screen.
* @type string $admin_preview_callback Callback function used to create the custom header markup in
* the Appearance > Header screen.
* }
*/
add_theme_support( 'custom-header', apply_filters( 'twentyfourteen_custom_header_args', array(
'default-text-color' => 'fff',
'width' => 1260,
'height' => 240,
'flex-height' => true,
'wp-head-callback' => 'twentyfourteen_header_style',
'admin-head-callback' => 'twentyfourteen_admin_header_style',
'admin-preview-callback' => 'twentyfourteen_admin_header_image',
) ) );
}
add_action( 'after_setup_theme', 'twentyfourteen_custom_header_setup' );
if ( ! function_exists( 'twentyfourteen_header_style' ) ) :
/**
* Styles the header image and text displayed on the blog
*
* @see twentyfourteen_custom_header_setup().
*
*/
function twentyfourteen_header_style() {
$text_color = get_header_textcolor();
// If no custom color for text is set, let's bail.
if ( display_header_text() && $text_color === get_theme_support( 'custom-header', 'default-text-color' ) )
return;
// If we get this far, we have custom styles.
?>
<style type="text/css" id="twentyfourteen-header-css">
<?php
// Has the text been hidden?
if ( ! display_header_text() ) :
?>
.site-title,
.site-description {
clip: rect(1px 1px 1px 1px); /* IE7 */
clip: rect(1px, 1px, 1px, 1px);
position: absolute;
}
<?php
// If the user has set a custom color for the text, use that.
elseif ( $text_color != get_theme_support( 'custom-header', 'default-text-color' ) ) :
?>
.site-title a {
color: #<?php echo esc_attr( $text_color ); ?>;
}
<?php endif; ?>
</style>
<?php
}
endif; // twentyfourteen_header_style
if ( ! function_exists( 'twentyfourteen_admin_header_style' ) ) :
/**
* Style the header image displayed on the Appearance > Header screen.
*
* @see twentyfourteen_custom_header_setup()
*
* @since Twenty Fourteen 1.0
*/
function twentyfourteen_admin_header_style() {
?>
<style type="text/css" id="twentyfourteen-admin-header-css">
.appearance_page_custom-header #headimg {
background-color: #000;
border: none;
max-width: 1260px;
min-height: 48px;
}
#headimg h1 {
font-family: Lato, sans-serif;
font-size: 18px;
line-height: 48px;
margin: 0 0 0 30px;
}
.rtl #headimg h1 {
margin: 0 30px 0 0;
}
#headimg h1 a {
color: #fff;
text-decoration: none;
}
#headimg img {
vertical-align: middle;
}
</style>
<?php
}
endif; // twentyfourteen_admin_header_style
if ( ! function_exists( 'twentyfourteen_admin_header_image' ) ) :
/**
* Create the custom header image markup displayed on the Appearance > Header screen.
*
* @see twentyfourteen_custom_header_setup()
*
* @since Twenty Fourteen 1.0
*/
function twentyfourteen_admin_header_image() {
?>
<div id="headimg">
<?php if ( get_header_image() ) : ?>
<img src="<?php header_image(); ?>" alt="">
<?php endif; ?>
<h1 class="displaying-header-text"><a id="name" style="<?php echo esc_attr( sprintf( 'color: #%s;', get_header_textcolor() ) ); ?>" onclick="return false;" href="<?php echo esc_url( home_url( '/' ) ); ?>" tabindex="-1"><?php bloginfo( 'name' ); ?></a></h1>
</div>
<?php
}
endif; // twentyfourteen_admin_header_image

View File

@@ -0,0 +1,115 @@
<?php
/**
* Twenty Fourteen Customizer support
*
* @package WordPress
* @subpackage Twenty_Fourteen
* @since Twenty Fourteen 1.0
*/
/**
* Implement Customizer additions and adjustments.
*
* @since Twenty Fourteen 1.0
*
* @param WP_Customize_Manager $wp_customize Customizer object.
*/
function twentyfourteen_customize_register( $wp_customize ) {
// Add postMessage support for site title and description.
$wp_customize->get_setting( 'blogname' )->transport = 'postMessage';
$wp_customize->get_setting( 'blogdescription' )->transport = 'postMessage';
$wp_customize->get_setting( 'header_textcolor' )->transport = 'postMessage';
// Rename the label to "Site Title Color" because this only affects the site title in this theme.
$wp_customize->get_control( 'header_textcolor' )->label = __( 'Site Title Color', 'twentyfourteen' );
// Rename the label to "Display Site Title & Tagline" in order to make this option extra clear.
$wp_customize->get_control( 'display_header_text' )->label = __( 'Display Site Title &amp; Tagline', 'twentyfourteen' );
// Add custom description to Colors and Background controls or sections.
if ( property_exists( $wp_customize->get_control( 'background_color' ), 'description' ) ) {
$wp_customize->get_control( 'background_color' )->description = __( 'May only be visible on wide screens.', 'twentyfourteen' );
$wp_customize->get_control( 'background_image' )->description = __( 'May only be visible on wide screens.', 'twentyfourteen' );
} else {
$wp_customize->get_section( 'colors' )->description = __( 'Background may only be visible on wide screens.', 'twentyfourteen' );
$wp_customize->get_section( 'background_image' )->description = __( 'Background may only be visible on wide screens.', 'twentyfourteen' );
}
// Add the featured content section in case it's not already there.
$wp_customize->add_section( 'featured_content', array(
'title' => __( 'Featured Content', 'twentyfourteen' ),
'description' => sprintf( __( 'Use a <a href="%1$s">tag</a> to feature your posts. If no posts match the tag, <a href="%2$s">sticky posts</a> will be displayed instead.', 'twentyfourteen' ),
esc_url( add_query_arg( 'tag', _x( 'featured', 'featured content default tag slug', 'twentyfourteen' ), admin_url( 'edit.php' ) ) ),
admin_url( 'edit.php?show_sticky=1' )
),
'priority' => 130,
'active_callback' => 'is_front_page',
) );
// Add the featured content layout setting and control.
$wp_customize->add_setting( 'featured_content_layout', array(
'default' => 'grid',
'sanitize_callback' => 'twentyfourteen_sanitize_layout',
) );
$wp_customize->add_control( 'featured_content_layout', array(
'label' => __( 'Layout', 'twentyfourteen' ),
'section' => 'featured_content',
'type' => 'select',
'choices' => array(
'grid' => __( 'Grid', 'twentyfourteen' ),
'slider' => __( 'Slider', 'twentyfourteen' ),
),
) );
}
add_action( 'customize_register', 'twentyfourteen_customize_register' );
/**
* Sanitize the Featured Content layout value.
*
* @since Twenty Fourteen 1.0
*
* @param string $layout Layout type.
* @return string Filtered layout type (grid|slider).
*/
function twentyfourteen_sanitize_layout( $layout ) {
if ( ! in_array( $layout, array( 'grid', 'slider' ) ) ) {
$layout = 'grid';
}
return $layout;
}
/**
* Bind JS handlers to make Customizer preview reload changes asynchronously.
*
* @since Twenty Fourteen 1.0
*/
function twentyfourteen_customize_preview_js() {
wp_enqueue_script( 'twentyfourteen_customizer', get_template_directory_uri() . '/js/customizer.js', array( 'customize-preview' ), '20131205', true );
}
add_action( 'customize_preview_init', 'twentyfourteen_customize_preview_js' );
/**
* Add contextual help to the Themes and Post edit screens.
*
* @since Twenty Fourteen 1.0
*/
function twentyfourteen_contextual_help() {
if ( 'admin_head-edit.php' === current_filter() && 'post' !== $GLOBALS['typenow'] ) {
return;
}
get_current_screen()->add_help_tab( array(
'id' => 'twentyfourteen',
'title' => __( 'Twenty Fourteen', 'twentyfourteen' ),
'content' =>
'<ul>' .
'<li>' . sprintf( __( 'The home page features your choice of up to 6 posts prominently displayed in a grid or slider, controlled by a <a href="%1$s">tag</a>; you can change the tag and layout in <a href="%2$s">Appearance &rarr; Customize</a>. If no posts match the tag, <a href="%3$s">sticky posts</a> will be displayed instead.', 'twentyfourteen' ), esc_url( add_query_arg( 'tag', _x( 'featured', 'featured content default tag slug', 'twentyfourteen' ), admin_url( 'edit.php' ) ) ), admin_url( 'customize.php' ), admin_url( 'edit.php?show_sticky=1' ) ) . '</li>' .
'<li>' . sprintf( __( 'Enhance your site design by using <a href="%s">Featured Images</a> for posts you&rsquo;d like to stand out (also known as post thumbnails). This allows you to associate an image with your post without inserting it. Twenty Fourteen uses featured images for posts and pages&mdash;above the title&mdash;and in the Featured Content area on the home page.', 'twentyfourteen' ), 'https://codex.wordpress.org/Post_Thumbnails#Setting_a_Post_Thumbnail' ) . '</li>' .
'<li>' . sprintf( __( 'For an in-depth tutorial, and more tips and tricks, visit the <a href="%s">Twenty Fourteen documentation</a>.', 'twentyfourteen' ), 'https://codex.wordpress.org/Twenty_Fourteen' ) . '</li>' .
'</ul>',
) );
}
add_action( 'admin_head-themes.php', 'twentyfourteen_contextual_help' );
add_action( 'admin_head-edit.php', 'twentyfourteen_contextual_help' );

View File

@@ -0,0 +1,531 @@
<?php
/**
* Twenty Fourteen Featured Content
*
* This module allows you to define a subset of posts to be displayed
* in the theme's Featured Content area.
*
* For maximum compatibility with different methods of posting users
* will designate a featured post tag to associate posts with. Since
* this tag now has special meaning beyond that of a normal tags, users
* will have the ability to hide it from the front-end of their site.
*/
class Featured_Content {
/**
* The maximum number of posts a Featured Content area can contain.
*
* We define a default value here but themes can override
* this by defining a "max_posts" entry in the second parameter
* passed in the call to add_theme_support( 'featured-content' ).
*
* @see Featured_Content::init()
*
* @since Twenty Fourteen 1.0
*
* @static
* @access public
* @var int
*/
public static $max_posts = 15;
/**
* Instantiate.
*
* All custom functionality will be hooked into the "init" action.
*
* @static
* @access public
* @since Twenty Fourteen 1.0
*/
public static function setup() {
add_action( 'init', array( __CLASS__, 'init' ), 30 );
}
/**
* Conditionally hook into WordPress.
*
* Theme must declare that they support this module by adding
* add_theme_support( 'featured-content' ); during after_setup_theme.
*
* If no theme support is found there is no need to hook into WordPress.
* We'll just return early instead.
*
* @static
* @access public
* @since Twenty Fourteen 1.0
*/
public static function init() {
$theme_support = get_theme_support( 'featured-content' );
// Return early if theme does not support Featured Content.
if ( ! $theme_support ) {
return;
}
/*
* An array of named arguments must be passed as the second parameter
* of add_theme_support().
*/
if ( ! isset( $theme_support[0] ) ) {
return;
}
// Return early if "featured_content_filter" has not been defined.
if ( ! isset( $theme_support[0]['featured_content_filter'] ) ) {
return;
}
$filter = $theme_support[0]['featured_content_filter'];
// Theme can override the number of max posts.
if ( isset( $theme_support[0]['max_posts'] ) ) {
self::$max_posts = absint( $theme_support[0]['max_posts'] );
}
add_filter( $filter, array( __CLASS__, 'get_featured_posts' ) );
add_action( 'customize_register', array( __CLASS__, 'customize_register' ), 9 );
add_action( 'admin_init', array( __CLASS__, 'register_setting' ) );
add_action( 'switch_theme', array( __CLASS__, 'delete_transient' ) );
add_action( 'save_post', array( __CLASS__, 'delete_transient' ) );
add_action( 'delete_post_tag', array( __CLASS__, 'delete_post_tag' ) );
add_action( 'customize_controls_enqueue_scripts', array( __CLASS__, 'enqueue_scripts' ) );
add_action( 'pre_get_posts', array( __CLASS__, 'pre_get_posts' ) );
add_action( 'wp_loaded', array( __CLASS__, 'wp_loaded' ) );
}
/**
* Hide "featured" tag from the front-end.
*
* Has to run on wp_loaded so that the preview filters of the Customizer
* have a chance to alter the value.
*
* @static
* @access public
* @since Twenty Fourteen 1.0
*/
public static function wp_loaded() {
if ( self::get_setting( 'hide-tag' ) ) {
add_filter( 'get_terms', array( __CLASS__, 'hide_featured_term' ), 10, 3 );
add_filter( 'get_the_terms', array( __CLASS__, 'hide_the_featured_term' ), 10, 3 );
}
}
/**
* Get featured posts.
*
* @static
* @access public
* @since Twenty Fourteen 1.0
*
* @return array Array of featured posts.
*/
public static function get_featured_posts() {
$post_ids = self::get_featured_post_ids();
// No need to query if there is are no featured posts.
if ( empty( $post_ids ) ) {
return array();
}
$featured_posts = get_posts( array(
'include' => $post_ids,
'posts_per_page' => count( $post_ids ),
) );
return $featured_posts;
}
/**
* Get featured post IDs
*
* This function will return the an array containing the
* post IDs of all featured posts.
*
* Sets the "featured_content_ids" transient.
*
* @static
* @access public
* @since Twenty Fourteen 1.0
*
* @return array Array of post IDs.
*/
public static function get_featured_post_ids() {
// Get array of cached results if they exist.
$featured_ids = get_transient( 'featured_content_ids' );
if ( false === $featured_ids ) {
$settings = self::get_setting();
$term = get_term_by( 'name', $settings['tag-name'], 'post_tag' );
if ( $term ) {
// Query for featured posts.
$featured_ids = get_posts( array(
'fields' => 'ids',
'numberposts' => self::$max_posts,
'suppress_filters' => false,
'tax_query' => array(
array(
'field' => 'term_id',
'taxonomy' => 'post_tag',
'terms' => $term->term_id,
),
),
) );
}
// Get sticky posts if no Featured Content exists.
if ( ! $featured_ids ) {
$featured_ids = self::get_sticky_posts();
}
set_transient( 'featured_content_ids', $featured_ids );
}
// Ensure correct format before return.
return array_map( 'absint', $featured_ids );
}
/**
* Return an array with IDs of posts maked as sticky.
*
* @static
* @access public
* @since Twenty Fourteen 1.0
*
* @return array Array of sticky posts.
*/
public static function get_sticky_posts() {
return array_slice( get_option( 'sticky_posts', array() ), 0, self::$max_posts );
}
/**
* Delete featured content ids transient.
*
* Hooks in the "save_post" action.
*
* @see Featured_Content::validate_settings().
*
* @static
* @access public
* @since Twenty Fourteen 1.0
*/
public static function delete_transient() {
delete_transient( 'featured_content_ids' );
}
/**
* Exclude featured posts from the home page blog query.
*
* Filter the home page posts, and remove any featured post ID's from it.
* Hooked onto the 'pre_get_posts' action, this changes the parameters of
* the query before it gets any posts.
*
* @static
* @access public
* @since Twenty Fourteen 1.0
*
* @param WP_Query $query WP_Query object.
* @return WP_Query Possibly-modified WP_Query.
*/
public static function pre_get_posts( $query ) {
// Bail if not home or not main query.
if ( ! $query->is_home() || ! $query->is_main_query() ) {
return;
}
// Bail if the blog page is not the front page.
if ( 'posts' !== get_option( 'show_on_front' ) ) {
return;
}
$featured = self::get_featured_post_ids();
// Bail if no featured posts.
if ( ! $featured ) {
return;
}
// We need to respect post ids already in the blacklist.
$post__not_in = $query->get( 'post__not_in' );
if ( ! empty( $post__not_in ) ) {
$featured = array_merge( (array) $post__not_in, $featured );
$featured = array_unique( $featured );
}
$query->set( 'post__not_in', $featured );
}
/**
* Reset tag option when the saved tag is deleted.
*
* It's important to mention that the transient needs to be deleted,
* too. While it may not be obvious by looking at the function alone,
* the transient is deleted by Featured_Content::validate_settings().
*
* Hooks in the "delete_post_tag" action.
*
* @see Featured_Content::validate_settings().
*
* @static
* @access public
* @since Twenty Fourteen 1.0
*
* @param int $tag_id The term_id of the tag that has been deleted.
*/
public static function delete_post_tag( $tag_id ) {
$settings = self::get_setting();
if ( empty( $settings['tag-id'] ) || $tag_id != $settings['tag-id'] ) {
return;
}
$settings['tag-id'] = 0;
$settings = self::validate_settings( $settings );
update_option( 'featured-content', $settings );
}
/**
* Hide featured tag from displaying when global terms are queried from the front-end.
*
* Hooks into the "get_terms" filter.
*
* @static
* @access public
* @since Twenty Fourteen 1.0
*
* @param array $terms List of term objects. This is the return value of get_terms().
* @param array $taxonomies An array of taxonomy slugs.
* @return array A filtered array of terms.
*
* @uses Featured_Content::get_setting()
*/
public static function hide_featured_term( $terms, $taxonomies, $args ) {
// This filter is only appropriate on the front-end.
if ( is_admin() ) {
return $terms;
}
// We only want to hide the featured tag.
if ( ! in_array( 'post_tag', $taxonomies ) ) {
return $terms;
}
// Bail if no terms were returned.
if ( empty( $terms ) ) {
return $terms;
}
// Bail if term objects are unavailable.
if ( 'all' != $args['fields'] ) {
return $terms;
}
$settings = self::get_setting();
foreach ( $terms as $order => $term ) {
if ( ( $settings['tag-id'] === $term->term_id || $settings['tag-name'] === $term->name ) && 'post_tag' === $term->taxonomy ) {
unset( $terms[ $order ] );
}
}
return $terms;
}
/**
* Hide featured tag from display when terms associated with a post object
* are queried from the front-end.
*
* Hooks into the "get_the_terms" filter.
*
* @static
* @access public
* @since Twenty Fourteen 1.0
*
* @param array $terms A list of term objects. This is the return value of get_the_terms().
* @param int $id The ID field for the post object that terms are associated with.
* @param array $taxonomy An array of taxonomy slugs.
* @return array Filtered array of terms.
*
* @uses Featured_Content::get_setting()
*/
public static function hide_the_featured_term( $terms, $id, $taxonomy ) {
// This filter is only appropriate on the front-end.
if ( is_admin() ) {
return $terms;
}
// Make sure we are in the correct taxonomy.
if ( 'post_tag' != $taxonomy ) {
return $terms;
}
// No terms? Return early!
if ( empty( $terms ) ) {
return $terms;
}
$settings = self::get_setting();
foreach ( $terms as $order => $term ) {
if ( ( $settings['tag-id'] === $term->term_id || $settings['tag-name'] === $term->name ) && 'post_tag' === $term->taxonomy ) {
unset( $terms[ $term->term_id ] );
}
}
return $terms;
}
/**
* Register custom setting on the Settings -> Reading screen.
*
* @static
* @access public
* @since Twenty Fourteen 1.0
*/
public static function register_setting() {
register_setting( 'featured-content', 'featured-content', array( __CLASS__, 'validate_settings' ) );
}
/**
* Add settings to the Customizer.
*
* @static
* @access public
* @since Twenty Fourteen 1.0
*
* @param WP_Customize_Manager $wp_customize Customizer object.
*/
public static function customize_register( $wp_customize ) {
$wp_customize->add_section( 'featured_content', array(
'title' => __( 'Featured Content', 'twentyfourteen' ),
'description' => sprintf( __( 'Use a <a href="%1$s">tag</a> to feature your posts. If no posts match the tag, <a href="%2$s">sticky posts</a> will be displayed instead.', 'twentyfourteen' ),
esc_url( add_query_arg( 'tag', _x( 'featured', 'featured content default tag slug', 'twentyfourteen' ), admin_url( 'edit.php' ) ) ),
admin_url( 'edit.php?show_sticky=1' )
),
'priority' => 130,
'theme_supports' => 'featured-content',
) );
// Add Featured Content settings.
$wp_customize->add_setting( 'featured-content[tag-name]', array(
'default' => _x( 'featured', 'featured content default tag slug', 'twentyfourteen' ),
'type' => 'option',
'sanitize_js_callback' => array( __CLASS__, 'delete_transient' ),
) );
$wp_customize->add_setting( 'featured-content[hide-tag]', array(
'default' => true,
'type' => 'option',
'sanitize_js_callback' => array( __CLASS__, 'delete_transient' ),
) );
// Add Featured Content controls.
$wp_customize->add_control( 'featured-content[tag-name]', array(
'label' => __( 'Tag Name', 'twentyfourteen' ),
'section' => 'featured_content',
'priority' => 20,
) );
$wp_customize->add_control( 'featured-content[hide-tag]', array(
'label' => __( 'Don&rsquo;t display tag on front end.', 'twentyfourteen' ),
'section' => 'featured_content',
'type' => 'checkbox',
'priority' => 30,
) );
}
/**
* Enqueue the tag suggestion script.
*
* @static
* @access public
* @since Twenty Fourteen 1.0
*/
public static function enqueue_scripts() {
wp_enqueue_script( 'featured-content-suggest', get_template_directory_uri() . '/js/featured-content-admin.js', array( 'jquery', 'suggest' ), '20131022', true );
}
/**
* Get featured content settings.
*
* Get all settings recognized by this module. This function
* will return all settings whether or not they have been stored
* in the database yet. This ensures that all keys are available
* at all times.
*
* In the event that you only require one setting, you may pass
* its name as the first parameter to the function and only that
* value will be returned.
*
* @static
* @access public
* @since Twenty Fourteen 1.0
*
* @param string $key The key of a recognized setting.
* @return mixed Array of all settings by default. A single value if passed as first parameter.
*/
public static function get_setting( $key = 'all' ) {
$saved = (array) get_option( 'featured-content' );
$defaults = array(
'hide-tag' => 1,
'tag-id' => 0,
'tag-name' => _x( 'featured', 'featured content default tag slug', 'twentyfourteen' ),
);
$options = wp_parse_args( $saved, $defaults );
$options = array_intersect_key( $options, $defaults );
if ( 'all' != $key ) {
return isset( $options[ $key ] ) ? $options[ $key ] : false;
}
return $options;
}
/**
* Validate featured content settings.
*
* Make sure that all user supplied content is in an expected
* format before saving to the database. This function will also
* delete the transient set in Featured_Content::get_featured_content().
*
* @static
* @access public
* @since Twenty Fourteen 1.0
*
* @param array $input Array of settings input.
* @return array Validated settings output.
*/
public static function validate_settings( $input ) {
$output = array();
if ( empty( $input['tag-name'] ) ) {
$output['tag-id'] = 0;
} else {
$term = get_term_by( 'name', $input['tag-name'], 'post_tag' );
if ( $term ) {
$output['tag-id'] = $term->term_id;
} else {
$new_tag = wp_create_tag( $input['tag-name'] );
if ( ! is_wp_error( $new_tag ) && isset( $new_tag['term_id'] ) ) {
$output['tag-id'] = $new_tag['term_id'];
}
}
$output['tag-name'] = $input['tag-name'];
}
$output['hide-tag'] = isset( $input['hide-tag'] ) && $input['hide-tag'] ? 1 : 0;
// Delete the featured post ids transient.
self::delete_transient();
return $output;
}
} // Featured_Content
Featured_Content::setup();

View File

@@ -0,0 +1,227 @@
<?php
/**
* Custom template tags for Twenty Fourteen
*
* @package WordPress
* @subpackage Twenty_Fourteen
* @since Twenty Fourteen 1.0
*/
if ( ! function_exists( 'twentyfourteen_paging_nav' ) ) :
/**
* Display navigation to next/previous set of posts when applicable.
*
* @since Twenty Fourteen 1.0
*
* @global WP_Query $wp_query WordPress Query object.
* @global WP_Rewrite $wp_rewrite WordPress Rewrite object.
*/
function twentyfourteen_paging_nav() {
global $wp_query, $wp_rewrite;
// Don't print empty markup if there's only one page.
if ( $wp_query->max_num_pages < 2 ) {
return;
}
$paged = get_query_var( 'paged' ) ? intval( get_query_var( 'paged' ) ) : 1;
$pagenum_link = html_entity_decode( get_pagenum_link() );
$query_args = array();
$url_parts = explode( '?', $pagenum_link );
if ( isset( $url_parts[1] ) ) {
wp_parse_str( $url_parts[1], $query_args );
}
$pagenum_link = remove_query_arg( array_keys( $query_args ), $pagenum_link );
$pagenum_link = trailingslashit( $pagenum_link ) . '%_%';
$format = $wp_rewrite->using_index_permalinks() && ! strpos( $pagenum_link, 'index.php' ) ? 'index.php/' : '';
$format .= $wp_rewrite->using_permalinks() ? user_trailingslashit( $wp_rewrite->pagination_base . '/%#%', 'paged' ) : '?paged=%#%';
// Set up paginated links.
$links = paginate_links( array(
'base' => $pagenum_link,
'format' => $format,
'total' => $wp_query->max_num_pages,
'current' => $paged,
'mid_size' => 1,
'add_args' => array_map( 'urlencode', $query_args ),
'prev_text' => __( '&larr; Previous', 'twentyfourteen' ),
'next_text' => __( 'Next &rarr;', 'twentyfourteen' ),
) );
if ( $links ) :
?>
<nav class="navigation paging-navigation" role="navigation">
<h1 class="screen-reader-text"><?php _e( 'Posts navigation', 'twentyfourteen' ); ?></h1>
<div class="pagination loop-pagination">
<?php echo $links; ?>
</div><!-- .pagination -->
</nav><!-- .navigation -->
<?php
endif;
}
endif;
if ( ! function_exists( 'twentyfourteen_post_nav' ) ) :
/**
* Display navigation to next/previous post when applicable.
*
* @since Twenty Fourteen 1.0
*/
function twentyfourteen_post_nav() {
// Don't print empty markup if there's nowhere to navigate.
$previous = ( is_attachment() ) ? get_post( get_post()->post_parent ) : get_adjacent_post( false, '', true );
$next = get_adjacent_post( false, '', false );
if ( ! $next && ! $previous ) {
return;
}
?>
<nav class="navigation post-navigation" role="navigation">
<h1 class="screen-reader-text"><?php _e( 'Post navigation', 'twentyfourteen' ); ?></h1>
<div class="nav-links">
<?php
if ( is_attachment() ) :
previous_post_link( '%link', __( '<span class="meta-nav">Published In</span>%title', 'twentyfourteen' ) );
else :
previous_post_link( '%link', __( '<span class="meta-nav">Previous Post</span>%title', 'twentyfourteen' ) );
next_post_link( '%link', __( '<span class="meta-nav">Next Post</span>%title', 'twentyfourteen' ) );
endif;
?>
</div><!-- .nav-links -->
</nav><!-- .navigation -->
<?php
}
endif;
if ( ! function_exists( 'twentyfourteen_posted_on' ) ) :
/**
* Print HTML with meta information for the current post-date/time and author.
*
* @since Twenty Fourteen 1.0
*/
function twentyfourteen_posted_on() {
if ( is_sticky() && is_home() && ! is_paged() ) {
echo '<span class="featured-post">' . __( 'Sticky', 'twentyfourteen' ) . '</span>';
}
// Set up and print post meta information.
printf( '<span class="entry-date"><a href="%1$s" rel="bookmark"><time class="entry-date" datetime="%2$s">%3$s</time></a></span> <span class="byline"><span class="author vcard"><a class="url fn n" href="%4$s" rel="author">%5$s</a></span></span>',
esc_url( get_permalink() ),
esc_attr( get_the_date( 'c' ) ),
esc_html( get_the_date() ),
esc_url( get_author_posts_url( get_the_author_meta( 'ID' ) ) ),
get_the_author()
);
}
endif;
/**
* Find out if blog has more than one category.
*
* @since Twenty Fourteen 1.0
*
* @return boolean true if blog has more than 1 category
*/
function twentyfourteen_categorized_blog() {
if ( false === ( $all_the_cool_cats = get_transient( 'twentyfourteen_category_count' ) ) ) {
// Create an array of all the categories that are attached to posts
$all_the_cool_cats = get_categories( array(
'hide_empty' => 1,
) );
// Count the number of categories that are attached to the posts
$all_the_cool_cats = count( $all_the_cool_cats );
set_transient( 'twentyfourteen_category_count', $all_the_cool_cats );
}
if ( 1 !== (int) $all_the_cool_cats ) {
// This blog has more than 1 category so twentyfourteen_categorized_blog should return true
return true;
} else {
// This blog has only 1 category so twentyfourteen_categorized_blog should return false
return false;
}
}
/**
* Flush out the transients used in twentyfourteen_categorized_blog.
*
* @since Twenty Fourteen 1.0
*/
function twentyfourteen_category_transient_flusher() {
// Like, beat it. Dig?
delete_transient( 'twentyfourteen_category_count' );
}
add_action( 'edit_category', 'twentyfourteen_category_transient_flusher' );
add_action( 'save_post', 'twentyfourteen_category_transient_flusher' );
if ( ! function_exists( 'twentyfourteen_post_thumbnail' ) ) :
/**
* Display an optional post thumbnail.
*
* Wraps the post thumbnail in an anchor element on index
* views, or a div element when on single views.
*
* @since Twenty Fourteen 1.0
* @since Twenty Fourteen 1.4 Was made 'pluggable', or overridable.
*/
function twentyfourteen_post_thumbnail() {
if ( post_password_required() || is_attachment() || ! has_post_thumbnail() ) {
return;
}
if ( is_singular() ) :
?>
<div class="post-thumbnail">
<?php
if ( ( ! is_active_sidebar( 'sidebar-2' ) || is_page_template( 'page-templates/full-width.php' ) ) ) {
the_post_thumbnail( 'twentyfourteen-full-width' );
} else {
the_post_thumbnail();
}
?>
</div>
<?php else : ?>
<a class="post-thumbnail" href="<?php the_permalink(); ?>" aria-hidden="true">
<?php
if ( ( ! is_active_sidebar( 'sidebar-2' ) || is_page_template( 'page-templates/full-width.php' ) ) ) {
the_post_thumbnail( 'twentyfourteen-full-width' );
} else {
the_post_thumbnail( 'post-thumbnail', array( 'alt' => get_the_title() ) );
}
?>
</a>
<?php endif; // End is_singular()
}
endif;
if ( ! function_exists( 'twentyfourteen_excerpt_more' ) && ! is_admin() ) :
/**
* Replaces "[...]" (appended to automatically generated excerpts) with ...
* and a Continue reading link.
*
* @since Twenty Fourteen 1.3
*
* @param string $more Default Read More excerpt link.
* @return string Filtered Read More excerpt link.
*/
function twentyfourteen_excerpt_more( $more ) {
$link = sprintf( '<a href="%1$s" class="more-link">%2$s</a>',
esc_url( get_permalink( get_the_ID() ) ),
/* translators: %s: Name of current post */
sprintf( __( 'Continue reading %s <span class="meta-nav">&rarr;</span>', 'twentyfourteen' ), '<span class="screen-reader-text">' . get_the_title( get_the_ID() ) . '</span>' )
);
return ' &hellip; ' . $link;
}
add_filter( 'excerpt_more', 'twentyfourteen_excerpt_more' );
endif;

View File

@@ -0,0 +1,269 @@
<?php
/**
* Custom Widget for displaying specific post formats
*
* Displays posts from Aside, Quote, Video, Audio, Image, Gallery, and Link formats.
*
* @link https://codex.wordpress.org/Widgets_API#Developing_Widgets
*
* @package WordPress
* @subpackage Twenty_Fourteen
* @since Twenty Fourteen 1.0
*/
class Twenty_Fourteen_Ephemera_Widget extends WP_Widget {
/**
* The supported post formats.
*
* @access private
* @since Twenty Fourteen 1.0
*
* @var array
*/
private $formats = array( 'aside', 'image', 'video', 'audio', 'quote', 'link', 'gallery' );
/**
* Constructor.
*
* @since Twenty Fourteen 1.0
*
* @return Twenty_Fourteen_Ephemera_Widget
*/
public function __construct() {
parent::__construct( 'widget_twentyfourteen_ephemera', __( 'Twenty Fourteen Ephemera', 'twentyfourteen' ), array(
'classname' => 'widget_twentyfourteen_ephemera',
'description' => __( 'Use this widget to list your recent Aside, Quote, Video, Audio, Image, Gallery, and Link posts.', 'twentyfourteen' ),
) );
}
/**
* Output the HTML for this widget.
*
* @access public
* @since Twenty Fourteen 1.0
*
* @param array $args An array of standard parameters for widgets in this theme.
* @param array $instance An array of settings for this widget instance.
*/
public function widget( $args, $instance ) {
$format = isset( $instance['format'] ) && in_array( $instance['format'], $this->formats ) ? $instance['format'] : 'aside';
switch ( $format ) {
case 'image':
$format_string = __( 'Images', 'twentyfourteen' );
$format_string_more = __( 'More images', 'twentyfourteen' );
break;
case 'video':
$format_string = __( 'Videos', 'twentyfourteen' );
$format_string_more = __( 'More videos', 'twentyfourteen' );
break;
case 'audio':
$format_string = __( 'Audio', 'twentyfourteen' );
$format_string_more = __( 'More audio', 'twentyfourteen' );
break;
case 'quote':
$format_string = __( 'Quotes', 'twentyfourteen' );
$format_string_more = __( 'More quotes', 'twentyfourteen' );
break;
case 'link':
$format_string = __( 'Links', 'twentyfourteen' );
$format_string_more = __( 'More links', 'twentyfourteen' );
break;
case 'gallery':
$format_string = __( 'Galleries', 'twentyfourteen' );
$format_string_more = __( 'More galleries', 'twentyfourteen' );
break;
case 'aside':
default:
$format_string = __( 'Asides', 'twentyfourteen' );
$format_string_more = __( 'More asides', 'twentyfourteen' );
break;
}
$number = empty( $instance['number'] ) ? 2 : absint( $instance['number'] );
$title = apply_filters( 'widget_title', empty( $instance['title'] ) ? $format_string : $instance['title'], $instance, $this->id_base );
$ephemera = new WP_Query( array(
'order' => 'DESC',
'posts_per_page' => $number,
'no_found_rows' => true,
'post_status' => 'publish',
'post__not_in' => get_option( 'sticky_posts' ),
'tax_query' => array(
array(
'taxonomy' => 'post_format',
'terms' => array( "post-format-$format" ),
'field' => 'slug',
'operator' => 'IN',
),
),
) );
if ( $ephemera->have_posts() ) :
$tmp_content_width = $GLOBALS['content_width'];
$GLOBALS['content_width'] = 306;
echo $args['before_widget'];
?>
<h1 class="widget-title <?php echo esc_attr( $format ); ?>">
<a class="entry-format" href="<?php echo esc_url( get_post_format_link( $format ) ); ?>"><?php echo esc_html( $title ); ?></a>
</h1>
<ol>
<?php
while ( $ephemera->have_posts() ) :
$ephemera->the_post();
$tmp_more = $GLOBALS['more'];
$GLOBALS['more'] = 0;
?>
<li>
<article <?php post_class(); ?>>
<div class="entry-content">
<?php
if ( has_post_format( 'gallery' ) ) :
if ( post_password_required() ) :
the_content( __( 'Continue reading <span class="meta-nav">&rarr;</span>', 'twentyfourteen' ) );
else :
$images = array();
$galleries = get_post_galleries( get_the_ID(), false );
if ( isset( $galleries[0]['ids'] ) )
$images = explode( ',', $galleries[0]['ids'] );
if ( ! $images ) :
$images = get_posts( array(
'fields' => 'ids',
'numberposts' => -1,
'order' => 'ASC',
'orderby' => 'menu_order',
'post_mime_type' => 'image',
'post_parent' => get_the_ID(),
'post_type' => 'attachment',
) );
endif;
$total_images = count( $images );
if ( has_post_thumbnail() ) :
$post_thumbnail = get_the_post_thumbnail();
elseif ( $total_images > 0 ) :
$image = reset( $images );
$post_thumbnail = wp_get_attachment_image( $image, 'post-thumbnail' );
endif;
if ( ! empty ( $post_thumbnail ) ) :
?>
<a href="<?php the_permalink(); ?>"><?php echo $post_thumbnail; ?></a>
<?php endif; ?>
<p class="wp-caption-text">
<?php
printf( _n( 'This gallery contains <a href="%1$s" rel="bookmark">%2$s photo</a>.', 'This gallery contains <a href="%1$s" rel="bookmark">%2$s photos</a>.', $total_images, 'twentyfourteen' ),
esc_url( get_permalink() ),
number_format_i18n( $total_images )
);
?>
</p>
<?php
endif;
else :
the_content( __( 'Continue reading <span class="meta-nav">&rarr;</span>', 'twentyfourteen' ) );
endif;
?>
</div><!-- .entry-content -->
<header class="entry-header">
<div class="entry-meta">
<?php
if ( ! has_post_format( 'link' ) ) :
the_title( '<h1 class="entry-title"><a href="' . esc_url( get_permalink() ) . '" rel="bookmark">', '</a></h1>' );
endif;
printf( '<span class="entry-date"><a href="%1$s" rel="bookmark"><time class="entry-date" datetime="%2$s">%3$s</time></a></span> <span class="byline"><span class="author vcard"><a class="url fn n" href="%4$s" rel="author">%5$s</a></span></span>',
esc_url( get_permalink() ),
esc_attr( get_the_date( 'c' ) ),
esc_html( get_the_date() ),
esc_url( get_author_posts_url( get_the_author_meta( 'ID' ) ) ),
get_the_author()
);
if ( ! post_password_required() && ( comments_open() || get_comments_number() ) ) :
?>
<span class="comments-link"><?php comments_popup_link( __( 'Leave a comment', 'twentyfourteen' ), __( '1 Comment', 'twentyfourteen' ), __( '% Comments', 'twentyfourteen' ) ); ?></span>
<?php endif; ?>
</div><!-- .entry-meta -->
</header><!-- .entry-header -->
</article><!-- #post-## -->
</li>
<?php endwhile; ?>
</ol>
<a class="post-format-archive-link" href="<?php echo esc_url( get_post_format_link( $format ) ); ?>">
<?php
/* translators: used with More archives link */
printf( __( '%s <span class="meta-nav">&rarr;</span>', 'twentyfourteen' ), $format_string_more );
?>
</a>
<?php
echo $args['after_widget'];
// Reset the post globals as this query will have stomped on it.
wp_reset_postdata();
$GLOBALS['more'] = $tmp_more;
$GLOBALS['content_width'] = $tmp_content_width;
endif; // End check for ephemeral posts.
}
/**
* Deal with the settings when they are saved by the admin.
*
* Here is where any validation should happen.
*
* @since Twenty Fourteen 1.0
*
* @param array $new_instance New widget instance.
* @param array $instance Original widget instance.
* @return array Updated widget instance.
*/
function update( $new_instance, $instance ) {
$instance['title'] = strip_tags( $new_instance['title'] );
$instance['number'] = empty( $new_instance['number'] ) ? 2 : absint( $new_instance['number'] );
if ( in_array( $new_instance['format'], $this->formats ) ) {
$instance['format'] = $new_instance['format'];
}
return $instance;
}
/**
* Display the form for this widget on the Widgets page of the Admin area.
*
* @since Twenty Fourteen 1.0
*
* @param array $instance
*/
function form( $instance ) {
$title = empty( $instance['title'] ) ? '' : esc_attr( $instance['title'] );
$number = empty( $instance['number'] ) ? 2 : absint( $instance['number'] );
$format = isset( $instance['format'] ) && in_array( $instance['format'], $this->formats ) ? $instance['format'] : 'aside';
?>
<p><label for="<?php echo esc_attr( $this->get_field_id( 'title' ) ); ?>"><?php _e( 'Title:', 'twentyfourteen' ); ?></label>
<input id="<?php echo esc_attr( $this->get_field_id( 'title' ) ); ?>" class="widefat" name="<?php echo esc_attr( $this->get_field_name( 'title' ) ); ?>" type="text" value="<?php echo esc_attr( $title ); ?>"></p>
<p><label for="<?php echo esc_attr( $this->get_field_id( 'number' ) ); ?>"><?php _e( 'Number of posts to show:', 'twentyfourteen' ); ?></label>
<input id="<?php echo esc_attr( $this->get_field_id( 'number' ) ); ?>" name="<?php echo esc_attr( $this->get_field_name( 'number' ) ); ?>" type="text" value="<?php echo esc_attr( $number ); ?>" size="3"></p>
<p><label for="<?php echo esc_attr( $this->get_field_id( 'format' ) ); ?>"><?php _e( 'Post format to show:', 'twentyfourteen' ); ?></label>
<select id="<?php echo esc_attr( $this->get_field_id( 'format' ) ); ?>" class="widefat" name="<?php echo esc_attr( $this->get_field_name( 'format' ) ); ?>">
<?php foreach ( $this->formats as $slug ) : ?>
<option value="<?php echo esc_attr( $slug ); ?>"<?php selected( $format, $slug ); ?>><?php echo esc_html( get_post_format_string( $slug ) ); ?></option>
<?php endforeach; ?>
</select>
<?php
}
}