'd9d9d9',
'text' => '000000',
'link' => '222222',
'border' => '404040',
'url' => 'ffffff',
);
}
// Set the content width based on the theme's design and stylesheet.
if ( ! isset( $content_width ) )
$content_width = 315;
// define widths
define( 'MIN_WIDTH', 560 );
define( 'MAX_WIDTH', 840 );
// Tell WordPress to run monotone_setup() when the 'after_setup_theme' hook is run.
add_action( 'after_setup_theme', 'monotone_setup' );
function monotone_setup() {
/**
* Make theme available for translation
* Translations can be filed in the /languages/ directory
*/
load_theme_textdomain( 'monotone', get_template_directory() . '/languages' );
// Add default posts and comments RSS feed links to head.
add_theme_support( 'automatic-feed-links' );
// Let WordPress manage the document title.
add_theme_support( 'title-tag' );
// This theme uses wp_nav_menu() in one location.
register_nav_menus( array(
'primary' => __( 'Primary Navigation', 'monotone' ),
) );
}
// Register widgetized areas
function monotone_widgets_init() {
register_sidebar( array(
'name' => __( 'Footer Area One', 'monotone' ),
'id' => 'sidebar-1',
'description' => __( 'An optional widget in the footer', 'monotone' ),
'before_widget' => '
',
'after_widget' => '
',
'before_title' => '',
) );
}
add_action( 'widgets_init', 'monotone_widgets_init' );
// filters and actions
add_action( 'wp_head', 'monotone_header_function' );
add_filter( 'the_content', 'monotone_image_scrape', 0 );
add_action( 'publish_post', 'monotone_image_setup' );
add_action( 'publish_page', 'monotone_image_setup' );
function monotone_header_function() {
global $vertical;
if ( ! is_archive() && ! is_search() ) : ?>
breaks YouTube videos.
*/
function monotone_replace_empty_tag( $m ) {
$no_replace = array( 'embed' ); // expand as required
if ( in_array( strtolower( $m[1] ), $no_replace ) )
return $m[0]; // return the original untouched
return '';
}
// remove image tag from post_content for display
function monotone_image_scrape( $entry ) {
// don't scrape the image for the feed
if ( is_feed() ) { return $entry; }
$entry = str_replace( '[/wp_caption]','', $entry );
$entry = str_replace( '[/caption]','', $entry );
//remove image tag
$entry = preg_replace( '/
]*src=(\"|\').+?(\1)[^>]*\/*>/','', $entry );
//remove any empty tags left by the scrape.
$entry = str_replace( '
', '', $entry );
$entry = preg_replace_callback( '|<([a-z]+)[^>]*>\s*\1>|i', 'monotone_replace_empty_tag', $entry );
$entry = preg_replace_callback( '|<([a-z]+)[^>]*>\s*\1>|i', 'monotone_replace_empty_tag', $entry );
$entry = preg_replace_callback( '|<([a-z]+)[^>]*>\s*\1>|i', 'monotone_replace_empty_tag', $entry );
return $entry;
}
// this resets post meta
function monotone_reset_colors( $post ) {
global $post;
delete_post_meta( $post->ID, 'image_md5' );
delete_post_meta( $post->ID, 'image_url' );
delete_post_meta( $post->ID, 'image_size' );
delete_post_meta( $post->ID, 'image_tag' );
delete_post_meta( $post->ID, 'image_color_base' );
delete_post_meta( $post->ID, 'image_colors' );
delete_post_meta( $post->ID, 'image_colors_bg' );
delete_post_meta( $post->ID, 'image_colors_fg' );
}
function monotone_image_setup( $postid ) {
global $post;
$post = get_post( $postid );
// get url
if ( ! preg_match( '/
]*)src=(\"|\')(.+?)(\2)([^>\/]*)\/*>/', $post->post_content, $matches ) ) {
monotone_reset_colors( $post );
return false;
}
// url setup
$post->image_url = $matches[3];
if ( ! $post->image_url = preg_replace( '/\?w\=[0-9]+/','', $post->image_url ) )
return false;
$post->image_url = esc_url( $post->image_url, 'raw' );
$previous_md5 = get_post_meta( $post->ID, 'image_md5', true );
$previous_url = get_post_meta( $post->ID, 'image_url', true );
if ( ( md5( $post->image_tag ) != $previous_md5 ) or ( $post->image_url != $previous_url ) ) {
monotone_reset_colors( $post );
add_post_meta( $post->ID, 'image_url', $post->image_url );
add_post_meta( $post->ID, 'image_md5', md5($post->image_tag ) );
//image tag setup
$extra = $matches[1].' '.$matches[5];
$extra = preg_replace( '/width=(\"|\')[0-9]+(\1)/','', $extra );
$extra = preg_replace( '/height=(\"|\')[0-9]+(\1)/','', $extra );
$width = ( monotone_is_vertical( $post->image_url ) ) ? MIN_WIDTH : MAX_WIDTH;
delete_post_meta( $post->ID, 'image_tag' );
add_post_meta( $post->ID, 'image_tag', '
' );
// get colors
monotone_get_all_colors( $post );
return false;
}
return true;
}
function monotone_is_vertical( $url ) {
global $post;
$size = get_post_meta( $post->ID, 'image_size', true );
if ( ! is_array( $size ) ) {
$properties = monotone_get_image_properties( $url );
$size = $properties['size'];
if ( ! empty( $size ) )
add_post_meta( $post->ID, 'image_size', $size );
}
if ( ! is_array( $size ) || ! isset( $size[0] ) || ! isset( $size[1] ) )
return false;
$post->image_width = $size[0];
if ( $size[0] <= $size[1] )
return true;
if ( $size[0] < MIN_WIDTH )
return true;
return false;
}
function monotone_the_image( $return = null ) {
global $post;
if ( get_post_status($post->ID) == 'private' ) {
if ( ! is_page() && ! current_user_can( 'read_private_posts' ) ) {
return false;
} elseif ( is_page() && ! current_user_can( 'read_private_pages' ) ) {
return false;
}
}
if ( post_password_required() )
return false;
$tag = get_post_meta( $post->ID, 'image_tag', true );
if ( ! $tag ) {
monotone_image_setup( $post->ID );
$tag = get_post_meta( $post->ID, 'image_tag', true );
}
$tag = preg_replace( '/width=(\"|\')[0-9]+(\1)/','', $tag );
$tag = preg_replace( '/height=(\"|\')[0-9]+(\1)/','', $tag );
if ( $return ) return wp_kses( $tag, wp_kses_allowed_html( 'post' ) ); /*else*/ echo wp_kses( $tag, wp_kses_allowed_html( 'post' ) );
}
function monotone_the_image_url( $return = null ) {
global $post;
$tag = get_post_meta( $post->ID, 'image_url', true );
if ( ! $tag ) {
monotone_image_setup( $post->ID );
$tag = get_post_meta( $post->ID, 'image_url', true );
}
if ( $return ) return $tag; /*else*/ echo esc_url( $tag );
}
function monotone_the_thumbnail() {
global $post;
$src = preg_replace( '/\?w\=[0-9]+/','?w=125', monotone_the_image( true ) );
if ( ! $src ) $src = '
';
$src = ''.$src.'
';
echo wp_kses( $src, wp_kses_allowed_html( 'post' ) );
}
function monotone_get_all_colors( $post ) {
$base = new stdClass;
//pull from DB
$base->bg = get_post_meta( $post->ID, 'image_colors_bg',true );
$base->fg = get_post_meta( $post->ID, 'image_colors_fg',true );
// show return variable if full
if ( $base->bg != '' && $base->fg != '' ) {
return $base;
} else {
// else, get the colors
include_once __DIR__ . '/csscolor.php' ;
$base = new CSS_Color( monotone_base_color( $post ) );
//set bg
$bg = $base->bg;
//set fg
$fg = $base->fg;
if ( add_post_meta( $post->ID, 'image_colors_bg', $bg, false )
&& add_post_meta( $post->ID, 'image_colors_fg', $fg, false ) ) return $base;
}
}
/**
* Ensure a string representing a color in hexadecimal notation is safe for
* use in css and database saves.
*
* @param string $hex Color in hexadecimal notation, with or without a leading "#".
* @return string Color in hexadecimal notation, or the string "transparent".
*/
function monotone_sanitize_color_hex( $hex, $prefix = '#' ) {
$hex = trim( (string) $hex );
if ( 0 === strpos( $hex, '#' ) )
$hex = substr( $hex, 1 );
elseif ( 0 === strpos( $hex, '%23' ) )
$hex = substr( $hex, 3 );
if ( 1 === preg_match( '/^[0-9a-fA-F]{6}$/', $hex ) )
return $prefix . $hex;
return 'transparent';
}
function monotone_print_stylesheet() {
// phpcs:disable WordPress.Security.EscapeOutput.OutputNotEscaped -- monotone_sanitize_color_hex() returns a validated hex value or the literal "transparent".
global $post;
$new_color = new StdClass();
$color = monotone_get_all_colors( $post );
// hack for array keys like -1 being stored in post_meta as 4294967295
foreach ( ( $color->bg ?? [] ) as $key => $value ) {
if ( is_int( $key ) && $key > 0 ) $key = -( 4294967296 - $key );
$new_color->bg[$key] = $value;
}
foreach ( ( $color->fg ?? [] ) as $key => $value ) {
if ( is_int( $key ) && $key > 0 ) $key = -( 4294967296 - $key );
$new_color->fg[$key] = $value;
}
$color = $new_color;
// end hack
?>
#page {
background-color:bg['-1'] ?? '' ); ?>;
color:fg['-2'] ?? '' ); ?>;
}
a, a:link, a:visited {
color: fg['-3'] ?? '' ); ?>;
}
a:hover, a:active {
color: bg['+2'] ?? '' ); ?>;
}
#header h1, #header h1 a, #header h1 a:link, #header h1 a:visited, #header h1 a:active {
color: fg['0'] ?? '' ); ?>;
}
#header h1 a:hover {
color: bg['+2'] ?? '' ); ?>;
}
.navigation a, .navigation a:link,
.navigation a:visited, .navigation a:active {
color: fg['0'] ?? '' ); ?>;
}
h1 a:hover, h2 a:hover, h3 a:hover, h4 a:hover, h5 a:hover h6 a:hover, .navigation a:hover {
color: fg['-2'] ?? '' ); ?>;
}
.description,
h3#respond,
#comments,
#content h1, #content #post h1, #content .content h1, h1 a, h1 a:link, h1 a:visited, h1 a:active,
#content h2, #content #post h2, #content .content h2, h2 a, h2 a:link, h2 a:visited, h2 a:active,
#content h3, #content #post h3, #content .content h3, h3 a, h3 a:link, h3 a:visited, h3 a:active,
#content h4, #content #post h4, #content .content h4, h4 a, h4 a:link, h4 a:visited, h4 a:active,
#content h5, #content #post h5, #content .content h5, h5 a, h5 a:link, h5 a:visited, h5 a:active,
#content h6, #content #post h6, #content .content h6, h6 a, h6 a:link, h6 a:visited, h6 a:active { /* Use the corresponding foreground color */
color: fg['-1'] ?? '' ); ?>;
}
#postmetadata, #commentform p, .commentlist li, #post, #postmetadata .sleeve, #post .sleeve, #content, h3#respond, h3#comments, #reply-title {
color: fg['-2'] ?? '' ); ?>;
border-color: fg['-2'] ?? '' ); ?>;
}public ) && -1 == $current_blog->public )
$url = apply_filters( 'wpcom_get_private_file', $url );
/* Ask the host for a small copy so it does the resizing. */
$url = add_query_arg( array( 'w' => 300 ), $url );
}
return $url;
}
/**
* Read an image over http.
*
* The response is capped and is only ever held in memory - nothing is
* written to disk or added to the media library.
*
* @param string $url Url to request.
* @return string Raw image data, or an empty string.
*/
function monotone_get_remote_image_body( $url ) {
$response = wp_safe_remote_get( $url, array(
'timeout' => MONOTONE_REMOTE_IMAGE_TIMEOUT,
'redirection' => 3,
'limit_response_size' => MONOTONE_REMOTE_IMAGE_MAX_BYTES,
) );
if ( is_wp_error( $response ) )
return '';
if ( 200 != wp_remote_retrieve_response_code( $response ) )
return '';
$type = wp_remote_retrieve_header( $response, 'content-type' );
if ( is_array( $type ) )
$type = reset( $type );
if ( 0 !== strpos( strtolower( (string) $type ), 'image/' ) )
return '';
$body = wp_remote_retrieve_body( $response );
if ( ! is_string( $body ) || '' === $body )
return '';
/* A response that reached the cap was cut short and cannot be trusted. */
if ( strlen( $body ) >= MONOTONE_REMOTE_IMAGE_MAX_BYTES )
return '';
return $body;
}
/**
* Color and dimensions of an image that is not stored on this server.
*
* Results are cached so a template render does not repeat the request on
* every page view.
*
* @param string $url Image url.
* @return array Color in hexadecimal notation and getimagesize() style dimensions.
*/
function monotone_get_remote_image_properties( $url ) {
$properties = array(
'color' => '',
'size' => array(),
);
$url = monotone_get_remote_image_url( $url );
if ( '' === $url )
return $properties;
$cache_key = 'monotone_image_' . md5( $url );
$cached = get_transient( $cache_key );
if ( is_array( $cached ) )
return wp_parse_args( $cached, $properties );
$body = monotone_get_remote_image_body( $url );
if ( monotone_is_supported_image_data( $body ) ) {
$size = getimagesizefromstring( $body );
if ( is_array( $size ) ) {
$properties['size'] = $size;
$image = monotone_create_image_from_string( $body, $size );
if ( $image ) {
$properties['color'] = monotone_sample_color( $image );
imagedestroy( $image );
}
}
}
unset( $body );
set_transient( $cache_key, $properties, DAY_IN_SECONDS );
return $properties;
}
/**
* Color and dimensions of the image a post is built around.
*
* Images in the media library are read from disk. Everything else,
* including a media library that is not stored on this server, falls back
* to a capped http request.
*
* @param string $url Image url.
* @return array Color in hexadecimal notation and getimagesize() style dimensions.
*/
function monotone_get_image_properties( $url ) {
static $memo = array();
$url = trim( (string) $url );
if ( isset( $memo[ $url ] ) )
return $memo[ $url ];
$color = '';
$size = array();
$has_local_file = false;
$attachment_id = monotone_get_attachment_id_from_url( $url );
if ( ! empty( $attachment_id ) ) {
$size = monotone_get_attachment_size( $attachment_id );
$path = monotone_get_attachment_path( $attachment_id );
if ( '' !== $path ) {
$has_local_file = true;
$image = monotone_create_image_from_path( $path );
if ( $image ) {
$color = monotone_sample_color( $image );
if ( empty( $size ) )
$size = array( imagesx( $image ), imagesy( $image ) );
imagedestroy( $image );
}
}
}
/*
* Only reach for the network when there is no file to read here. A
* local file that will not decode would not decode over http either.
*/
if ( ! $has_local_file ) {
$remote = monotone_get_remote_image_properties( $url );
$color = $remote['color'];
if ( empty( $size ) )
$size = $remote['size'];
}
$memo[ $url ] = array(
'color' => ( '' === $color ) ? 'ffffff' : $color,
'size' => $size,
);
return $memo[ $url ];
}
/**
* Sample the representative color of an image resource.
*
* Samples five points based on the rule of thirds and the center, and
* uses the lower left point, matching this theme's long standing look.
*
* @param resource|GdImage $im Image resource.
* @return string Color in hexadecimal notation, or an empty string.
*/
function monotone_sample_color( $im ) {
$height = imagesy( $im );
$width = imagesx( $im );
if ( $width < 1 || $height < 1 )
return '';
$topy = min( $height - 1, round( $height / 3 ) );
$bottomy = min( $height - 1, round( ( $height / 3 ) * 2 ) );
$leftx = min( $width - 1, round( $width / 3 ) );
$rightx = min( $width - 1, round( ( $width / 3 ) * 2 ) );
$centery = min( $height - 1, round( $height / 2 ) );
$centerx = min( $width - 1, round( $width / 2 ) );
$rgb = array(
1 => imagecolorat( $im, $leftx, $topy ),
2 => imagecolorat( $im, $rightx, $topy ),
3 => imagecolorat( $im, $leftx, $bottomy ),
4 => imagecolorat( $im, $rightx, $bottomy ),
5 => imagecolorat( $im, $centerx, $centery ),
);
foreach ( $rgb as $value ) {
if ( false === $value )
return '';
}
$hex = array();
for ( $i = 1; $i <= 5; $i++ ) {
$r = ( $rgb[$i] >> 16 ) & 0xFF;
$g = ( $rgb[$i] >> 8 ) & 0xFF;
$b = $rgb[$i] & 0xFF;
$hex[$i] = monotone_rgbhex( $r, $g, $b );
}
return $hex[3];
}
function monotone_base_color( $post ) {
$url = get_post_meta( $post->ID, 'image_url', true );
if ( ! $url ) {
monotone_image_setup( $post->ID );
$url = get_post_meta( $post->ID, 'image_url', true );
}
$properties = monotone_get_image_properties( $url );
return $properties['color'];
}
function monotone_rgbhex( $red, $green, $blue ) {
return sprintf( '%02X%02X%02X', $red, $green, $blue );
}
// force 24 posts per page for archives
function monotone_posts_per_page() {
return 24;
}
add_filter( 'pre_option_posts_per_page', 'monotone_posts_per_page' );
function monotone_page_menu() {
global $wpdb; // fallback for primary navigation ?>
id="comment-">
is_main_query() )
return;
$query->set( 'posts_per_page', 1 );
$query->set( 'ignore_sticky_posts', true );
}
add_action( 'pre_get_posts', 'monotone_home_posts' );
/**
* WP.com: Show a nice admin message noting that the current theme has been
* trumped by a newer one.
*/
function monotone_add_notice() {
$current_theme = wp_get_theme()->Name;
if ( ! get_user_meta( get_current_user_id(), "$current_theme-theme-update", true ) ) {
add_settings_error(
'theme-update',
'theme-update',
sprintf(
__( 'Howdy! Your current theme, %1$s, has seen an update in the form of a brand new theme, %2$s. For more information, check out our blog post introducing %2$s to the world. %5$s' ),
$current_theme, // Old theme
'Duotone', // New theme
admin_url( 'themes.php?s=duotone' ), // Link to new theme
esc_url( 'http://en.blog.wordpress.com/2009/12/24/new-theme-duotone/' ), // Link to announcement post
sprintf( '×', __( 'Dismiss' ) ) // Dismiss
),
'updated'
);
remove_action( 'admin_notices', 'show_tip' );
if ( ! has_filter( 'admin_notices', 'settings_errors' ) )
add_action( 'admin_notices', 'settings_errors' );
wp_enqueue_script( 'dismiss-theme-update', get_template_directory_uri() . '/js/dismiss-theme-update.js', array( 'jquery' ), 20130225 );
wp_localize_script( 'dismiss-theme-update', 'dismissThemeUpdate', array(
'theme' => $current_theme,
'nonce' => wp_create_nonce( "$current_theme-theme-update" ),
) );
}
}
add_action( 'admin_init', 'monotone_add_notice' );
/**
* Updates user setting when theme update notice was dismissed.
*/
function monotone_dismiss_theme_update() {
$current_theme = wp_get_theme()->Name;
check_ajax_referer( "$current_theme-theme-update", 'nonce' );
if ( $_REQUEST['theme'] == $current_theme ) {
update_user_meta( get_current_user_id(), "$current_theme-theme-update", true );
wp_die( 1 );
}
}
add_action( 'wp_ajax_dismiss_theme_update', 'monotone_dismiss_theme_update' );