Skip to content
Oliver Harrison edited this page Jul 29, 2022 · 12 revisions

wd_s offers a handful of hooks and filters to tap into and customize WordPress functionality. Here is a list of what we include and how to use it in your theme.

Adds Body Classes

body_classes

Usage: add_filter( 'body_class', __NAMESPACE__ . '\body_classes' );

Output: Adds class names to the <body> tag based on the location, template type, or browser type.

Location: /inc/hooks/body-classes.php

Adds Defer Attribute

add_defer_attribute

Adds a 'defer' attribute to a specified enqueued script, by handle.

Usage:

function add_defer_attribute( $tag, $handle ) {

 $scripts_to_defer = [ 'wds-alpine' ];

 foreach ( $scripts_to_defer as $defer_script ) {
  if ( $defer_script === $handle ) {
   return str_replace( ' src', ' defer="defer" src', $tag );
  }
 }

 return $tag;
}
add_filter( 'script_loader_tag', __NAMESPACE__ . '\add_defer_attribute', 10, 2 );

Location: /inc/hooks.php

Adds OG Meta Tags

add_og_tags

Sometimes a client doesn't use Yoast SEO or another SEO plugin. In those cases, we still want to make sure they have reliable meta tags in place to display robust post cards when content is shared via Facebook, Twitter, etc.

This hook first checks for Yoast and bails if it is active – we don't need to output 2x meta tags.

If Yoast isn't active, we build our meta tags based on a set of conditions as we go:

  • Single posts and pages (but not the front page)
  • Category, Tag, and Custom Taxonomy archives
  • Search Results
  • Blog archive
  • Front page
  • Post Type archives
  • Media pages

Usage:

<?php
function add_og_tags() {
 // Bail if Yoast is installed, since it will handle things.
 if ( class_exists( 'WPSEO_Options' ) ) {
  return '';
 }

 // Set a post global on single posts. This avoids grabbing content from the first post on an archive page.
 if ( is_singular() ) {
  global $post;
 }

 // Get the post content.
 $post_content = ! empty( $post ) ? $post->post_content : '';

 // Strip all tags from the post content we just grabbed.
 $default_content = ( $post_content ) ? wp_strip_all_tags( strip_shortcodes( $post_content ) ) : $post_content;

 // Set our default title.
 $default_title = get_bloginfo( 'name' );

 // Set our default URL.
 $default_url = get_permalink();

 // Set our base description.
 $default_base_description = ( get_bloginfo( 'description' ) ) ? get_bloginfo( 'description' ) : esc_html__( 'Visit our website to learn more.', 'wds' );

 // Set the card type.
 $default_type = 'article';

 // Get our custom logo URL. We'll use this on archives and when no featured image is found.
 $logo_id    = get_theme_mod( 'custom_logo' );
 $logo_image = ( $logo_id ) ? wp_get_attachment_image_src( $logo_id, 'full' ) : '';
 $logo_url   = ( $logo_id ) ? $logo_image[0] : '';

 // Set our final defaults.
 $card_title            = $default_title;
 $card_description      = $default_base_description;
 $card_long_description = $default_base_description;
 $card_url              = $default_url;
 $card_image            = $logo_url;
 $card_type             = $default_type;

 // Let's start overriding!
 // All singles.
 if ( is_singular() ) {

  if ( has_post_thumbnail() ) {
   $card_image = get_the_post_thumbnail_url();
  }
 }

 // Single posts/pages that aren't the front page.
 if ( is_singular() && ! is_front_page() ) {

  $card_title            = get_the_title() . ' - ' . $default_title;
  $card_description      = ( $default_content ) ? wp_trim_words( $default_content, 53, '...' ) : $default_base_description;
  $card_long_description = ( $default_content ) ? wp_trim_words( $default_content, 140, '...' ) : $default_base_description;
 }

 // Categories, Tags, and Custom Taxonomies.
 if ( is_category() || is_tag() || is_tax() ) {

  $term_name      = single_term_title( '', false );
  $card_title     = $term_name . ' - ' . $default_title;
  $specify        = ( is_category() ) ? esc_html__( 'categorized in', 'wds' ) : esc_html__( 'tagged with', 'wds' );
  $queried_object = get_queried_object();
  $card_url       = get_term_link( $queried_object );
  $card_type      = 'website';

  // Translators: get the term name.
  $card_long_description = sprintf( esc_html__( 'Posts %1$s %2$s.', 'wds' ), $specify, $term_name );
  $card_description      = $card_long_description;
 }

 // Search results.
 if ( is_search() ) {

  $search_term = get_search_query();
  $card_title  = $search_term . ' - ' . $default_title;
  $card_url    = get_search_link( $search_term );
  $card_type   = 'website';

  // Translators: get the search term.
  $card_long_description = sprintf( esc_html__( 'Search results for %s.', 'wds' ), $search_term );
  $card_description      = $card_long_description;
 }

 if ( is_home() ) {

  $posts_page = get_option( 'page_for_posts' );
  $card_title = get_the_title( $posts_page ) . ' - ' . $default_title;
  $card_url   = get_permalink( $posts_page );
  $card_type  = 'website';
 }

 // Front page.
 if ( is_front_page() ) {

  $front_page = get_option( 'page_on_front' );
  $card_title = ( $front_page ) ? get_the_title( $front_page ) . ' - ' . $default_title : $default_title;
  $card_url   = get_home_url();
  $card_type  = 'website';
 }

 // Post type archives.
 if ( is_post_type_archive() ) {

  $post_type_name = get_post_type();
  $card_title     = $post_type_name . ' - ' . $default_title;
  $card_url       = get_post_type_archive_link( $post_type_name );
  $card_type      = 'website';
 }

 // Media page.
 if ( is_attachment() ) {
  $attachment_id = get_the_ID();
  $card_image    = ( wp_attachment_is_image( $attachment_id ) ) ? wp_get_attachment_image_url( $attachment_id, 'full' ) : $card_image;
 }

 ?>
 <meta property="og:title" content="<?php echo esc_attr( $card_title ); ?>" />
 <meta property="og:description" content="<?php echo esc_attr( $card_description ); ?>" />
 <meta property="og:url" content="<?php echo esc_url( $card_url ); ?>" />
 <?php if ( $card_image ) : ?>
  <meta property="og:image" content="<?php echo esc_url( $card_image ); ?>" />
 <?php endif; ?>
 <meta property="og:site_name" content="<?php echo esc_attr( $default_title ); ?>" />
 <meta property="og:type" content="<?php echo esc_attr( $card_type ); ?>" />
 <meta name="description" content="<?php echo esc_attr( $card_long_description ); ?>" />
 <?php
}

add_action( 'wp_head', __NAMESPACE__ . '\add_og_tags' );

Output:

<meta property="og:title" content="Featured Image (Vertical) - wd_s" />
<meta
  property="og:description"
  content="This post should display a featured image, if the theme supports it. Non-square images can provide some unique styling issues. This post tests a vertical featured image."
/>
<meta
  property="og:url"
  content="https://wdunderscores.test/2013/03/15/featured-image-vertical/"
/>
<meta
  property="og:image"
  content="https://wdunderscores.test/wp-content/uploads/2013/03/featured-image-vertical.jpg"
/>
<meta property="og:site_name" content="wd_s" />
<meta property="og:type" content="article" />
<meta
  name="description"
  content="This post should display a featured image, if the theme supports it. Non-square images can provide some unique styling issues. This post tests a vertical featured image."
/>

Location: /inc/hooks/add-og-tags.php

Flush Categorized Blog Transient

category_transient_flusher

Flush out the transients used in wd_s_categorized_blog.

Usage: <?php add_action( 'save_post', __NAMESPACE__ . '\category_transient_flusher' ); ?> <?php add_action( 'delete_category', __NAMESPACE__ . '\category_transient_flusher' ); ?>

Output: No output. By hooking into save_post or delete_category, we are assured that the transient is flushed each time a post is saved or a category deleted.

Location: /inc/hooks/category-transient-flusher.php

Custom Read More Link

content_more_link

Customize "Read More" string on with the_content();

Usage:

function content_more_link() {
 return ' <a class="more-link" href="' . get_permalink() . '">' . esc_html__( 'Read More', '_s' ) . '...</a>';
}
add_filter( 'the_content_more_link', __NAMESPACE__ . '\content_more_link' );

Output: <a class="more-link" href="https://wdunderscores.test/2013/03/15/more-tag/">Read More…</a>

Location: /inc/hooks/content-more-link.php

Custom Excerpt More Output

excerpt_more

Customize the [...] on the_excerpt()

Usage:

function excerpt_more( $more ) {
 return sprintf( ' <a class="more-link" href="%1$s">%2$s</a>', get_permalink( get_the_ID() ), esc_html__( 'Read more...', '_s' ) );
}
add_filter( 'excerpt_more',  __NAMESPACE__ . '\excerpt_more' );

Output: <a class="more-link" href="https://wdunderscores.test/2013/01/11/markup-and-formatting/">Read more…</a>

Location: /inc/hooks/excerpt-more.php

Filter Content Output

get_post_content

Filters WYSIWYG content with the_content filter.

Usage:

function get_post_content( $content ) {
 return ! empty( $content ) ? $content : false;
}

add_filter( 'the_content', __NAMESPACE__ . '\get_post_content', 20 );

Location: /inc/hooks/get-post-content.php

Add SVG Support

custom_mime_types

Add custom mime types to allow for uploading SVG images.

Usage:

function custom_mime_types( $mimes ) {
 $mimes['svg']  = 'image/svg+xml';
 $mimes['svgz'] = 'image/svg+xml';

 return $mimes;
}

add_filter( 'upload_mimes', __NAMESPACE__ . '\custom_mime_types' );;

Location: /inc/hooks/custom-mime-types.php

Add SVG Icons

include_svg_icons

Adds SVG definitions to the footer so they can be displayed via our SVG template tag.

Usage:

function include_svg_icons() {
 // Define SVG sprite file.
 $svg_icons = get_template_directory() . '/build/images/icons/sprite.svg';

 // If it exists, include it.
 if ( file_exists( $svg_icons ) ) {
  echo '<div class="svg-sprite-wrapper">';
  require_once $svg_icons;
  echo '</div>';
 }
}

add_action( 'wp_footer', __NAMESPACE__ . '\include_svg_icons', 9999 );

Location: /inc/hooks/include-svg-icons.php

Get Header Scripts

print_customizer_header_scripts

Get scripts from customizer field to output in the header. More info in the Customizer Wiki.

Location: /inc/hooks/print-customizer-header-scripts.php

Get Footer Scripts

display_customizer_footer_scripts

Get scripts from customizer field to output in the footer. More info in the Customizer Wiki.

Location: /inc/hooks/print-customizer-footer-scripts.php

Remove Archive Title Prefix

remove_archive_title_prefix

Removes or Adjusts the prefix on category archive page titles.

Usage: add_filter( 'get_the_archive_title', __NAMESPACE__ . '\remove_archive_title_prefix' );

Output: Archive or Category title as archive name with no suffix.

Location: /inc/hooks/remove-archive-title-prefix.php

Remove Empty p Tags From Gutenberg

disable_wpautop_for_gutenberg

Disables wpautop to remove empty p tags in rendered Gutenberg blocks.

Usage:

function disable_wpautop_for_gutenberg() {
 // If we have blocks in place, don't add wpautop.
 if ( has_filter( 'the_content', 'wpautop' ) && has_blocks() ) {
  remove_filter( 'the_content', 'wpautop' );
 }
}

add_filter( 'init', __NAMESPACE__ . '\disable_wpautop_for_gutenberg', 9 );

Location: /inc/hooks/disable-wpautop-for-gutenberg.php