Settings -> Media isset($content_width) or $content_width = get_option('large_size_w'); \is_numeric($content_width) or $content_width = 1024; # Use the generic 'theme' as the textdomain such that it is easier to # repurpose code in other themes. Few translations are needed here. # @link codex.wordpress.org/I18n_for_WordPress_Developers # @link ottopress.com/2012/internationalization-youre-probably-doing-it-wrong/ # @link markjaquith.wordpress.com/2011/10/06/translating-wordpress-plugins-and-themes-dont-get-clever/ # Actions to be run on the 'after_setup_theme' hook: add_action('after_setup_theme', function() { \defined('WP_DEBUG') && WP_DEBUG ? \add_filter('@modes', function($arr) { return $arr ? \array_unique( !($arr[] = 'debug') ?: $arr) : array('debug'); }) : remove_action('wp_head', 'wp_generator'); # tighten security add_editor_style(); # codex.wordpress.org/Function_Reference/add_editor_style add_theme_support('automatic-feed-links'); # required add_theme_support('post-thumbnails'); # "featured image" # codex.wordpress.org/Custom_Backgrounds # see _custom_background_cb in wp-includes/theme.php add_theme_support('custom-background', array( 'wp-head-callback' => function() { $image = get_background_image(); $image and $image = set_url_scheme($image); $style = $image ? \array_reduce(array( array('repeat', array('repeat', 'no-repeat', 'repeat-x', 'repeat-y'), 'repeat', '') , array('position_x', array('left', 'center', 'right'), 'position', 'top ') , array('attachment', array('scroll', 'fixed'), 'attachment', '') ), function($image, $arr) { $option = \get_theme_mod('background_' . $arr[0]); $option = \in_array($option, $arr[1]) ? $option : $arr[1][0]; $image[] = 'background-' . $arr[2] . ':' . $arr[3] . $option . ';'; return $image; }, array('background-image' => "background-image:url('$image');") ) : array(); $color = get_background_color(); $color and $style[] = "background-color:#$color;"; if ($style and $selector = apply_filters('@background_selector', '.custom-background')) { $style = $selector . '{' . \implode('', $style) . '}'; $media = apply_filters('@background_media', 'screen'); $media and $style = "@media $media{" . $style . '}'; echo apply_filters('@background_style', "\n"); } } )); }, 0); # Basic contextual support. add_filter('body_class', function($arr) { global $wp_registered_sidebars; if ( ! empty($wp_registered_sidebars)) foreach ($wp_registered_sidebars as $k => $v) is_active_sidebar($k) and $arr[] = "has-$k-widgets"; foreach (\apply_filters('@modes', array()) as $v) \strlen($v = sanitize_key($v)) and $arr[] = 'mode-' . $v; return \array_unique(\array_merge(array( is_child_theme() ? 'child-theme' : 'parent-theme' , is_singular() ? 'singular' : 'plural' ), $arr)); }); add_filter('@html_tag', function() { # Emulate language_attributes() b/c it has no "get" version. # Include its 'language_attributes' filter for plugin usage. $attrs = 'dir="' . (is_rtl() ? 'rtl' : 'ltr') . '" lang="' . get_bloginfo('language') . '"'; $attrs = apply_filters('language_attributes', $attrs); $class = get_body_class(); \in_array('void-avatars', $class) and add_filter('@comment_avatar', '__return_false'); \in_array('void-thumbnails', $class) and add_filter('@thumbnail', '__return_false'); \array_unshift($class, 'no-js', 'custom'); $class = \implode(' ', \array_unique($class)); add_filter('body_class', '__return_empty_array'); #wp $attrs .= " class='$class'"; $attrs .= ' itemscope'; # implied http://schema.org/WebPage $attrs = apply_filters('@html_attrs', $attrs); return ""; }, 0); add_action('@body', apply_filters('@body_actions', function() { # github.com/ryanve/action/issues/4 $skip = '' . __('skip', 'theme') . ''; $skip = apply_filters('@skip_anchor', $skip); if ($skip and $skip = \trim(\strip_tags($skip, ''))) { echo "\n" . \str_repeat(' ', 4) . $skip . "\n\n"; } foreach (array( array(5, 'get_header') , array(10, function() { locate_template('main.php', true, false); }) , array(30, 'get_footer') ) as $fn) { has_action('@body', $fn[1]) or add_action('@body', $fn[1], $fn[0]); } }), 0); add_action('@header', function() { locate_template('branding.php', true, false); }, apply_filters('@branding_priority', 10)); add_action(apply_filters('@menu_location', '@header'), function() { # Favor classes over IDs. add_filter('nav_menu_item_id', '__return_false'); add_filter('nav_menu_css_class', function($arr, $item = null) { if (\is_array($arr) && \is_object($item) && isset($item->ID)) \in_array($item = 'menu-item-' . $item->ID, $arr) or $arr[] = $item; return $arr; }, 10, 2); $items = apply_filters('@menu_items', '%3$s'); # for li pre-/appends $menu = apply_filters('@menu_attrs', 'id="menu" role="navigation" class="site-nav arrestive"'); $menu = "'; $menu = \str_repeat(' ', 8) . $menu . "\n\n"; echo apply_filters('@menu', $menu); }, apply_filters('@menu_priority', 10)); add_action('@header', function() { is_active_sidebar('header') and get_sidebar('header'); }); add_action('@footer', function() { is_active_sidebar('footer') and get_sidebar('footer'); }); add_action('widgets_init', function() { $areas = (array) apply_filters('@widget_areas', array( # Correlate names to CSS selectors: array('id' => 'main' , 'name' => '.main-widget-area') , array('id' => 'header' , 'name' => '.header-widget-area') , array('id' => 'footer' , 'name' => '.footer-widget-area') )); # codex.wordpress.org/Function_Reference/register_sidebar # Merge in sensible defaults: foreach ($areas as $a) { $a and register_sidebar(\array_merge(array( 'before_widget' => '
  • ' ), $a)); } }); # CPTs/taxos/menus/js/css should register on init. # Early-priority init actions: add_action('init', function() { # Register menus register_nav_menus(array('menu' => 'Menu')); # Register CSS # handle, uri, deps, ver, media $is_child = is_child_theme(); $index = trailingslashit(get_template_directory_uri()); wp_register_style('parent-base', $index . 'base.css', array(), null, null); wp_register_style('parent-style', $index . 'style.css', array('parent-base'), null, $is_child ? null : 'screen'); # Enqueue CSS # github.com/ryanve/action/issues/2 $is_child || is_admin() or wp_enqueue_style('parent-style'); }, 1); # Frontend-only normal-priority init actions: is_admin() or add_action('init', function() { # codex.wordpress.org/Migrating_Plugins_and_Themes_to_2.7/Enhanced_Comment_Display is_singular() and wp_enqueue_script('comment-reply'); # near plugin territory / useful to child themes / has no effect by default if ($gaq = apply_filters('@gaq', array())) { if ($gaq = \is_scalar($gaq) ? \json_decode($gaq) : $gaq) { if ($ga_uri = apply_filters('@ga_uri', 'http://www.google-analytics.com/ga.js')) { wp_enqueue_script('ga', $ga_uri, array(), null, true); wp_localize_script('ga', '_gaq', $gaq); # wp_localize_script will json_encode } } } }); add_action('@main', apply_filters('@main_actions', function() { get_template_part('loop', is_singular() ? 'singular' : 'plural'); is_active_sidebar('main') and get_sidebar('main'); })); \array_reduce(array('previous', 'next'), function($void, $rel) { $hook = $rel . '_posts_link_attributes'; $rel = \substr($rel, 0, 4); add_filter($hook, function($attrs = '') use ($rel) { $attrs or $attrs = ''; return \is_string($attrs) ? \ltrim($attrs . " rel='$rel' class='$rel'") : $attrs; }); }, null); add_action('@loop', apply_filters('@loop_actions', function() { static $ran; if ($ran = null !== $ran) return; # prevent from running more than once add_action('@loop', function() { is_singular() or locate_template('loop-header.php', true, false); }, 5); add_action('@loop', function() { # the actual loop if ( ! have_posts()) locate_template('loop-empty.php', true, false); else for ($path = locate_template('entry.php', false); have_posts();) { the_post(); require $path; } }, 10); add_action('@loop', function() { locate_template('loop-nav.php', true, false); }, 20); add_action('@loop_nav', apply_filters('@loop_nav_actions', is_singular() ? function() { previous_post_link('%link'); next_post_link('%link'); } : function() { $prev = '' . __('Prev', 'theme') . ''; $next = '' . __('Next', 'theme') . ''; posts_nav_link(' ', $prev, $next); })); }), 0); add_action('@loop_header', function() { $data = array(); if (is_category() || is_tag() || is_tax()) { $data['case'] = 'tax'; $data['name'] = single_term_title( '', false ); $data['description'] = term_description( '', get_query_var( 'taxonomy' ) ); } elseif (is_author()) { $data = get_queried_object(); $data = array('case' => 'user', 'name' => $data->display_name, 'description' => $data->user_description); } elseif (is_search()) { $data['case'] = 'search'; $data['name'] = __('Search: ', 'theme') . get_search_query(); } elseif (is_date()) { $data['case'] = 'date'; $parts = \explode('/', \ltrim($_SERVER['REQUEST_URI'], '/')); $data['name'] = array(); while (\is_numeric($n = \array_shift($parts))) $data['name'][] = $n; $data['name'] = \implode('-', $data['name']); $data['description'] = __('Archives.', 'theme'); } elseif (is_post_type_archive()) { $data['name'] = post_type_archive_title(); $data['description'] = get_post_type_object(get_query_var('post_type'))->description; } if ($data = apply_filters('@loop_data', $data)) { $data = \array_replace(\array_fill_keys(array('name', 'image', 'case'), null), $data); $data['case'] = $data['case'] ? \preg_replace('#[^\w\s-]+#', '', $data['case']) : ''; $data['class'] = 'loop ' . $data['case'] . ' '; $makeClass = function($prop) use ($data) { return \trim(\preg_replace('#\s+#', '-' . $prop . ' ', $data['class'])); }; ($markup = $data['image'] = $data['image'] ?: '') and \ctype_graph($src = \strip_tags($data['image'])) and ($alt = \htmlentities(\strip_tags($data['name']), ENT_QUOTES, null, false)) and $markup = '$alt"; foreach (array('name' => 'h1', 'description' => 'div') as $prop => $tagname) { if (isset($data[$prop])) { $class = $makeClass($prop); $markup .= "<$tagname itemprop='$prop' class='$class'>" . $data[$prop] . ""; } } echo $markup; } }, 5); add_action('@entry', apply_filters('@entry_actions', function() { static $ran, $content_mode; # allow the '@content_mode' to be changed between iterations # truthy => content | falsey => excerpt $content_mode = (bool) apply_filters('@content_mode', is_singular()); if ($ran = null !== $ran) return; # prevent adding the hooks more than once current_theme_supports('post-thumbnails') and add_filter('@thumbnail', function() use (&$content_mode) { if ( ! $content_mode and $size = apply_filters('@thumbnail_size', 'thumbnail')) if ($img = get_the_post_thumbnail(null, $size, array('itemprop' => 'image'))) return ($url = get_permalink()) && \strip_tags($img, '') === $img ? "" : $img; }, 0); add_action('@entry', function() { locate_template('entry-header.php', true, false); }, 5); add_action('@entry', function() use (&$content_mode) { locate_template($content_mode ? 'entry-content.php' : 'entry-summary.php', true, false); }, 10); add_action('@entry', function() use (&$content_mode) { $content_mode and locate_template('entry-footer.php', true, false); }, 15); is_singular() and add_action('@entry', function() { comments_template('/comments.php', true); }, 20); }), 0); add_filter('@entry_attrs', function($attrs = '') { $class = \implode(' ', get_post_class()); return "class='$class' itemscope itemtype='http://schema.org/Article'"; }, 0); add_filter('post_class', function($arr = array()) { $arr = (array) $arr; # This compares using the format from: Settings > General > Date Format # Maybe we should use Y-m-d or provide a filter like: # $format = apply_filters( '@time_compare_format', '' ); $arr[] = get_the_date() === get_the_modified_date() ? 'unrevised' : 'revised'; $arr[] = has_post_thumbnail() ? 'has-thumbnail' : 'lacks-thumbnail'; return \array_unique($arr); }); add_action('@entry_header', function() { echo apply_filters('@thumbnail', null); $markup = '

    '; $markup .= '

    '; echo apply_filters('@headline', $markup); }, 5); add_action('@entry_header', function() { global $authordata; $markup = "
    "; \is_object($authordata) and ($link = get_author_posts_url($authordata->ID, $authordata->user_nicename)) # href and ($link = "') and ($link = apply_filters('the_author_posts_link', $link)) #wp: the_author_posts_link() and $markup .= '
    ' . __('By', 'theme') . '
    ' . $link . '
    '; $time_item = function($arr) { \extract($arr); $date = \call_user_func($fn); # Settings > General > Date Format $w3c = \call_user_func($fn, DATE_W3C); # php.net/manual/en/class.datetime.php $idx = get_year_link(\strtok($w3c, '-')); $rel and $rel = ' rel="index"'; $date = "$date"; $tag = ""; $tag = apply_filters('@' . $hook . '_tag', $tag, $date); $item = '
    ' . $label . '
    '; return $item . '
    ' . $tag . '
    '; }; # microformats.org/wiki/hentry # schema.org/Article # github.com/ryanve/action/issues/1 $markup .= $time_item(array( 'fn' => 'get_the_date' , 'itemprop' => 'datePublished' , 'label' => 'Posted' , 'class' => 'published' , 'hook' => 'published' , 'rel' => 'index' )); $markup .= $time_item(array( 'fn' => 'get_the_modified_date' , 'itemprop' => 'dateModified' , 'label' => 'Updated' , 'class' => 'updated' , 'hook' => 'modified' , 'rel' => '' )); $markup .= '
    '; echo apply_filters('@byline', $markup); }, 7); add_action('@entry_footer', function() { global $wp_taxonomies; static $taxos; echo apply_filters('@entry_pages', wp_link_pages(array( 'echo' => 0 , 'before' => '' ))); isset($taxos) or $taxos = \wp_list_pluck($wp_taxonomies, 'label'); $id = get_the_ID(); $type = get_post_type($id); $markup = ''; foreach ($taxos as $name => $label) { if (is_object_in_taxonomy($type, $name)) { if ($class = sanitize_html_class(\mb_strtolower($label))) { $terms = get_the_term_list($id, $name, '
  • ', '
  • ', '
  • '); $void = $terms ? '' : ' void'; $markup .= "
    $label
    "; $markup .= "
    "; $markup .= '
    '; } } } $markup = '
    ' . $markup . '
    '; echo apply_filters('@entry_terms', $markup, $taxos); }, 20); # Clean excerpt whitespace add_filter('the_excerpt', 'normalize_whitespace'); # wp add_filter('the_excerpt', 'trim'); # @link github.com/ryanve/action/issues/1 # add hcard classes to the link if there's not already any classes add_filter('the_author_posts_link', function($tag) { return \strpos($tag, 'class=') ? $tag : \str_replace(' href=', ' class="url fn n" href=', $tag); }); # Urgent actions: # meta[charset] add_action('wp_head', function() { $tag = ''; echo \ltrim(apply_filters('@meta_charset', $tag) . "\n"); }, -5); # [dns-prefetch] markup add_action('wp_head', function() { $uris = (array) apply_filters('@dns_prefetches', array()); echo \implode('', \array_reduce($uris, function($result, $uri) { \ctype_graph($uri) and ($uri = \explode('//', $uri)) and isset($uri[1]) # only deal with full uris and ($uri = \strtok($uri[1], '/')) # strip to authority and (false === \strpos($uri, $_SERVER['SERVER_NAME'])) # don't prefetch self and ! \preg_match('#[^\w@:_.-]#', $uri) # ensure remaining uri is entirely safe and $result[$uri] = "\n"; return $result; }, array())); }, -4); # [dns-prefetch] uris add_action('@dns_prefetches', function($uris) { global $wp_scripts, $wp_styles; foreach (array($wp_scripts, $wp_styles) as $o) { \is_object($o) and !empty($o->queue) and !empty($o->registered) and $uris = \array_merge($uris, \array_intersect_key( (array) \wp_list_pluck($o->registered, 'src') , \array_flip(\array_values((array) $o->queue)) )); } return $uris; }); # title add_action('wp_head', function() { $tag = ($tag = \trim(apply_filters('@title_attrs', ''))) ? "" : '<title>'; $tag = apply_filters('@title_tag', $tag . get_the_title() . ''); if ($tag and $tag = \trim($tag)) echo "\n$tag\n\n"; }, -3); # meta add_action('wp_head', function() { foreach (apply_filters('@meta', array( 'viewport' => array('name' => 'viewport', 'content' => 'width=device-width,initial-scale=1.0') )) as $tag) { if (\is_string($tag)) { $tag = \strip_tags($tag, ''); } elseif ($tag && isset($tag['content'])) { $attrs = array(); foreach($tag as $k => $v) { if (false !== $v && \is_scalar($v)) $attrs[] = true === $v || '' === ($v = $v ? esc_attr($v) : $v) ? $k : "$k='$v'"; } $attrs = \implode(' ', $attrs); $tag = $attrs ? "" : null; } else { continue; } if ($tag) echo "$tag\n"; } }, -1); # Remove WP gallery