posts ) { $classes[] = 'no-posts'; } } if ( class_exists( 'Jetpack' ) && Jetpack::is_module_active( 'infinite-scroll' ) ) { $classes[] = 'infinite-scroll'; } return $classes; } add_filter( 'body_class', 'chained_body_classes' ); /** * Extend the default WordPress post classes. * * @since chained 1.0 * * @param array $classes A list of existing post class values. * @return array The filtered post class list. */ function chained_post_classes( $classes ) { if ( is_archive() || is_home() || is_search() ) { $classes[] = 'entry-card js-masonry-item'; } $classes[] = 'post-design-default'; if ( has_post_thumbnail() ) { if ( 'standard' === get_post_format() ) { $classes[] = 'has-post-thumbnail'; } } return $classes; } add_filter( 'post_class', 'chained_post_classes', 10, 1 ); /*----------------------------------------------------------------------------------------------- Chained Comments @package v1.0.0 ------------------------------------------------------------------------------------------------- */ if ( !function_exists( 'chained_comment' ) ) { /** * Display individual comment layout * * @since chained 1.0 */ function chained_comment( $comment, $args, $depth ) { static $comment_number ; if ( !isset( $comment_number ) ) { $comment_number = $args['per_page'] * ($args['page'] - 1) + 1; } else { $comment_number++; } ?>
  • >
    %s', get_comment_author_link() ); ?>
    comment_approved ) { ?>

    ' . $link . ''; } return $link; } add_filter( 'wp_link_pages_link', 'chained_link_pages' ); /** * Wrap more link */ function chained_read_more_link( $link ) { return ''; } add_filter( 'the_content_more_link', 'chained_read_more_link' ); /** * Constrain the excerpt length to 35 words - about a medium sized excerpt */ function chained_excerpt_length( $length ) { return 35; } add_filter( 'excerpt_length', 'chained_excerpt_length', 999 ); /** * Replace the suchainedit input with button in Search Form */ function chained_search_form( $form ) { $form = ''; return $form; } add_filter( 'get_search_form', 'chained_search_form' ); /* * Due to the fact that we need a wrapper for center aligned images and for the ones with alignnone, we need to wrap the images without a caption * The images with captions already are wrapped by the figure tag */ function chained_wrap_images_in_figure( $content ) { $classes = array( 'aligncenter', 'alignnone' ); foreach ( $classes as $class ) { //this regex basically tells this //match all the images that are not in captions and that have the X class //when an image is wrapped by an anchor tag, match that too $regex = '~\\[caption[^\\]]*\\].*\\[\\/caption\\]|((?:]*>\\s*)?]*>(?:\\s*<\\/a>)?)~i'; $callback = new chainedWrapImagesInFigureCallback( $class ); // Replace the matches $content = preg_replace_callback( $regex, // in the callback function, if Group 1 is empty, // set the replacement to the whole match, // i.e. don't replace array( $callback, 'callback' ), $content ); } return $content; } add_filter( 'the_content', 'chained_wrap_images_in_figure' ); //We need to use a class so we can pass the $class variable to the callback function class chainedWrapImagesInFigureCallback { private $class ; function __construct( $class ) { $this->class = $class; } public function callback( $match ) { if ( empty($match[1]) ) { return $match[0]; } return '' . $match[1] . ''; } } /** * This function was borrowed from CakePHP and adapted. * https://github.com/cakephp/cakephp/blob/53fdb18655119d4cca966d769b6c33f8eaaa8da0/src/Utility/Text.php * * Bellow is the copyright notice: * * ======================== * * CakePHP(tm) : Rapid Development Framework (http://cakephp.org) * Copyright (c) Cake Software Foundation, Inc. (http://cakefoundation.org) * * Licensed under The MIT License * * ======================== * * Truncates text. * * Cuts a string to the length of $length and replaces the last characters * with the ellipsis if the text is longer than length. * * ### Options: * * - `ellipsis` Will be used as ending and appended to the trimmed string * - `exact` If false, $text will not be cut mid-word * - `html` If true, HTML tags would be handled correctly * * @param string $text String to truncate. * @param int $length Length of returned string, including ellipsis. * @param array $options An array of HTML attributes and options. * @return string Trimmed string. * @link http://book.cakephp.org/3.0/en/core-libraries/string.html#truncating-text */ function chained_truncate( $text, $length = 100, $options = array() ) { $default = array( 'ellipsis' => apply_filters( 'chained_excerpt_more', '\\xe2\\x80\\xa6' ), 'exact' => false, 'html' => false, ); if ( !empty($options['html']) && strtolower( mb_internal_encoding() ) === 'utf-8' ) { $default['ellipsis'] = "…"; } $options = array_merge( $default, $options ); extract( $options ); if ( true === $html ) { if ( mb_strlen( preg_replace( '/<.*?>/', '', $text ) ) <= $length ) { return $text; } $totalLength = mb_strlen( strip_tags( $ellipsis ) ); $openTags = array(); $truncate = ''; preg_match_all( '/(<\\/?([\\w+]+)[^>]*>)?([^<>]*)/', $text, $tags, PREG_SET_ORDER ); foreach ( $tags as $tag ) { if ( !preg_match( '/img|br|input|hr|area|base|basefont|col|frame|isindex|link|meta|param/s', $tag[2] ) ) { if ( preg_match( '/<[\\w]+[^>]*>/s', $tag[0] ) ) { array_unshift( $openTags, $tag[2] ); } elseif ( preg_match( '/<\\/([\\w]+)[^>]*>/s', $tag[0], $closeTag ) ) { $pos = array_search( $closeTag[1], $openTags ); if ( false !== $pos ) { array_splice( $openTags, $pos, 1 ); } } } $truncate .= $tag[1]; $contentLength = mb_strlen( preg_replace( '/&[0-9a-z]{2,8};|&#[0-9]{1,7};|&#x[0-9a-f]{1,6};/i', ' ', $tag[3] ) ); if ( $contentLength + $totalLength > $length ) { $left = $length - $totalLength; $entitiesLength = 0; if ( preg_match_all( '/&[0-9a-z]{2,8};|&#[0-9]{1,7};|&#x[0-9a-f]{1,6};/i', $tag[3], $entities, PREG_OFFSET_CAPTURE ) ) { foreach ( $entities[0] as $entity ) { if ( $entity[1] + 1 - $entitiesLength <= $left ) { $left--; $entitiesLength += mb_strlen( $entity[0] ); } else { break; } } } $truncate .= mb_substr( $tag[3], 0, $left + $entitiesLength ); break; } else { $truncate .= $tag[3]; $totalLength += $contentLength; } if ( $totalLength >= $length ) { break; } } } else { if ( mb_strlen( $text ) <= $length ) { return $text; } $truncate = mb_substr( $text, 0, $length - mb_strlen( $ellipsis ) ); } if ( false === $exact ) { $spacepos = mb_strrpos( $truncate, ' ' ); if ( true === $html ) { $truncateCheck = mb_substr( $truncate, 0, $spacepos ); $lastOpenTag = mb_strrpos( $truncateCheck, '<' ); $lastCloseTag = mb_strrpos( $truncateCheck, '>' ); if ( $lastOpenTag > $lastCloseTag ) { preg_match_all( '/<[\\w]+[^>]*>/s', $truncate, $lastTagMatches ); $lastTag = array_pop( $lastTagMatches[0] ); $spacepos = mb_strrpos( $truncate, $lastTag ) + mb_strlen( $lastTag ); } $bits = mb_substr( $truncate, $spacepos ); preg_match_all( '/<\\/([a-z]+)>/', $bits, $droppedTags, PREG_SET_ORDER ); if ( !empty($droppedTags) ) { if ( !empty($openTags) ) { foreach ( $droppedTags as $closingTag ) { if ( !in_array( $closingTag[1], $openTags ) ) { array_unshift( $openTags, $closingTag[1] ); } } } else { foreach ( $droppedTags as $closingTag ) { $openTags[] = $closingTag[1]; } } } } $truncate = mb_substr( $truncate, 0, $spacepos ); // If truncate still empty, then we don't need to count ellipsis in the cut. if ( 0 === mb_strlen( $truncate ) ) { $truncate = mb_substr( $text, 0, $length ); } } $truncate .= $ellipsis; if ( true === $html ) { foreach ( $openTags as $tag ) { $truncate .= ''; } } return $truncate; } /*----------------------------------------------------------------------------------------------- Add Classes to Linked Images @package v1.0.0 ------------------------------------------------------------------------------------------------- */ function chained_add_classes_to_linked_images( $content ) { $classes = 'img-link'; // can do multiple classes, separate with space $patterns = array(); $replacements = array(); //first if it has class with single quotes $patterns[0] = '/]*)class=\'([^\']*)\'([^>]*)>\\s*]*)>\\s*<\\/a>/'; // matches img tag wrapped in anchor tag where anchor has existing classes contained in single quotes $replacements[0] = ''; //second if it has class with double quotes $patterns[1] = '/]*)class="([^"]*)"([^>]*)>\\s*]*)>\\s*<\\/a>/'; // matches img tag wrapped in anchor tag where anchor has existing classes contained in double quotes $replacements[1] = ''; //third no class attribute $patterns[2] = '/]*class)([^>]*)>\\s*]*)>\\s*<\\/a>/'; // matches img tag wrapped in anchor tag where anchor tag where anchor has no existing classes $replacements[2] = ''; //make sure that we respected the desired order of execution ksort( $patterns ); ksort( $replacements ); $content = preg_replace( $patterns, $replacements, $content ); return $content; } add_filter( 'the_content', 'chained_add_classes_to_linked_images', 99, 1 ); /*----------------------------------------------------------------------------------------------- Post Loop Item Classes @package v1.0.0 ------------------------------------------------------------------------------------------------- */ function chained_get_blog_class( $class = '' ) { $classes = array(); $classes[] = 'masonry'; // items per row $items_per_row = get_theme_mod( 'chained_masonry_num_of_cols', 4 ); $items_per_row_at_desktop = min( max( $items_per_row - 1, 1 ), 4 ); $items_per_row_at_tablet = min( max( $items_per_row - 2, 1 ), 3 ); $items_per_row_class = "masonry--" . $items_per_row . "col-bighd masonry--" . $items_per_row_at_desktop . "col-desktop grid--" . $items_per_row_at_tablet . "col-tablet"; $classes[] = $items_per_row_class; if ( !empty($class) ) { if ( !is_array( $class ) ) { $class = preg_split( '#\\s+#', $class ); } $classes = array_merge( $classes, $class ); } else { // Ensure that we always coerce class to being an array. $class = array(); } $classes = array_map( 'esc_attr', $classes ); return join( ' ', array_unique( $classes ) ); } /** * Display the classes for the blog wrapper. * * @param string|array $class Optional. One or more classes to add to the class list. * @param string|array $location Optional. The place (template) where the classes are displayed. This is a hint for filters. */ function chained_blog_class( $class = '' ) { // Separates classes with a single space, collates classes echo 'class="' . esc_attr( chained_get_blog_class( $class ) ) . '"' ; } /** * Wrap embedded videos in a class, to fix responsive issues on issues */ function chained_wrap_embed_with_div( $html, $url, $attr ) { return '
    ' . $html . '
    '; } add_filter( 'embed_oembed_html', 'chained_wrap_embed_with_div', 10, 3 ); /** * Set the content width in pixels, based on the theme's design and stylesheet. * * Priority 0 to make it available to lower priority callbacks. * * @global int $chained_content_width */ function chained_content_width() { $GLOBALS['chained_content_width'] = apply_filters( 'chained_content_width', 1600, 0 ); } add_action( 'after_setup_theme', 'chained_content_width', 0 ); /*----------------------------------------------------------------------------------------------- Comment Layout @package v1.0.0 ------------------------------------------------------------------------------------------------- */ function chained_comments( $comment, $args, $depth ) { static $comment_number ; if ( !isset( $comment_number ) ) { $comment_number = $args['per_page'] * ($args['page'] - 1) + 1; } else { $comment_number++; } ?>
  • >
    comment_ID ) == 'comment' ) { ?> %s', get_comment_author_link() ); ?>
    comment_approved == '0' ) { ?>

    0 ) { /* translators: reading estimate time */ $word_count_strings = sprintf( _n( '%s minute ', '%s minutes', number_format_i18n( $word_per_min ), 'chained' ), number_format_i18n( $word_per_min ) ); if ( 'post' == get_post_type( $post_id ) ) { echo '' ; echo esc_html( $word_count_strings ) ; echo '' ; } } if ( absint( $word_per_min ) == Null ) { echo '' ; echo esc_html_e( '0 min', 'chained' ) ; echo '' ; } } } /*----------------------------------------------------------------------------------------------- Allowed HTML TAGS @package v1.0.1 ------------------------------------------------------------------------------------------------- */ function chained_allowed_html() { $allowed_tags = array( 'a' => array( 'class' => array(), 'href' => array(), 'rel' => array(), 'title' => array(), ), 'abbr' => array( 'title' => array(), ), 'b' => array(), 'blockquote' => array( 'cite' => array(), ), 'cite' => array( 'title' => array(), ), 'code' => array(), 'del' => array( 'datetime' => array(), 'title' => array(), ), 'dd' => array(), 'div' => array( 'class' => array(), 'title' => array(), 'style' => array(), ), 'dl' => array(), 'dt' => array(), 'em' => array(), 'h1' => array(), 'h2' => array(), 'h3' => array(), 'h4' => array(), 'h5' => array(), 'h6' => array(), 'i' => array(), 'img' => array( 'alt' => array(), 'class' => array(), 'height' => array(), 'src' => array(), 'width' => array(), ), 'li' => array( 'class' => array(), ), 'ol' => array( 'class' => array(), ), 'p' => array( 'class' => array(), ), 'q' => array( 'cite' => array(), 'title' => array(), ), 'span' => array( 'class' => array(), 'title' => array(), 'style' => array(), ), 'strike' => array(), 'strong' => array(), 'ul' => array( 'class' => array(), ), ); return $allowed_tags; }