Skip to content

A poorly organized collection of Wordpress notes and code

Notifications You must be signed in to change notification settings

hightowerc87/wordpress-notes

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

5 Commits
 
 

Repository files navigation

wordpress-notes

A poorly organized collection of Wordpress notes and code

WP Code

Content Editor Image Fix

Themes created using our blank template might not include the correct style rules for floating images in the WordPress Content editor, add this code near the top of the stylesheet:
img.alignright {float: right; margin: 0 0 1em 1em;}
img.alignleft {float: left; margin: 0 1em 1em 0;}
img.aligncenter {display: block; margin-left: auto; margin-right: auto;}
.alignright {float: right;}
.alignleft {float: left;}
.aligncenter {display: block; margin-left: auto; margin-right: auto;}

The Loop in Action

Basic loop to get the content (and title, etc.) of whatever page or post you're currently on
<?php
   if (have_posts()) : while (have_posts()) : the_post();
        the_title();
        the_content();
   endwhile; endif;
?>

Query (loop) through custom post type

Queries custom post type by name and loops through the content of each. Can also grab the title or any custom fields this way. wp_reset_query(); restores the $wp_query and global post data to the original main query in case other queries are needed on the page.
<?php 
     $args = array( 'post_type' => 'product', 'posts_per_page' => -1, 'orderby' => 'menu_order', 'order' => 'ASC' );
     $loop = new WP_Query( $args ); while ( $loop->have_posts() ) : $loop->the_post(); ?>
         -- stuff goes here --
<?php endwhile; wp_reset_query(); ?>

Loop through Custom Post Type by Custom Taxonomies

<?php
// A term is an item of a taxonomy (e.g. "Promotional" could be a term for the taxonomy "video_type")
// ...so $categories could be $terms and it would still make sense
$categories = get_terms('taxonomy_name');
foreach( $categories as $category ):
?>
  <section class="category-<?php echo $category ?>">
    <h2><?php echo $category->name; // Print the cat title ?></h2>
    <p class="description"><?php echo $category->description ?></p>
    <div class="<?php echo $category->post_type ?>-list">
      <?php
      //select posts in this category (term), and of a specified content type (post type) 
      $posts = get_posts(array(
        'post_type' => 'custom_post_type_name',
        'taxonomy' => $category->taxonomy,
        'term' => $category->slug,
        'nopaging' => true, // to show all posts in this category, could also use 'numberposts' => -1 instead
      ));
      foreach($posts as $post): // begin cycle through posts of this category
        setup_postdata($post); //set up post data for use in the loop (enables the_title(), etc without specifying a post ID)
      ?>
        // Now you can do things with the post and display it, like so
        <article id="post-<?php the_ID(); ?>" <?php post_class(); ?>>
          <h3><?php the_title(); ?></h3>
          <?php 
            // Getting custom field data example
            echo get_post_meta($post->ID, 'field_key', true); 
          ?>
          <?php the_content() ?>
        </article>
      <?php endforeach; ?>
    </div>
  </section>
<?php endforeach; ?>

Loop through each custom post in current custom taxonomy

 <?php
$cat_name = 'portfolio_cat';
 $current_cat_name = get_the_term_list( $post->ID, $cat_name );

$custom_taxterms = wp_get_object_terms( $post->ID, $cat_name, array('fields' => 'ids') );

$args = array( 'post_type' => 'portfolio', 'post_status' => 'publish', 'posts_per_page' => -1, 'orderby' => 'menu_order', 'order' => 'ASC', 'tax_query' => array( array( 'taxonomy' => $cat_name, 'field' => 'id', 'terms' => $custom_taxterms ) ) ); $related_items = new WP_Query( $args ); if ($related_items->have_posts()) : while ( $related_items->have_posts() ) : $related_items->the_post(); echo '<a class="here-sone" href="'.get_permalink().'"><li>'.get_the_title().'</li></a>'; endwhile; endif; wp_reset_query(); ?>

List Categories of Custom Post Type and link to first available post per category

 <?php 
 $cat_name = 'cat_name';
 $categories = get_terms($cat_name);
 foreach( $categories as $category ):

$the_query = new WP_Query( array( "posts_per_page" => 1, "orderby" => 'date', "order" => 'DESC', "tax_query" => array( array ( 'taxonomy' => $cat_name, // use the $cat_name you define at the top of your script 'field' => 'term_id', 'terms' => $category->term_id, // use the current term in your foreach loop ), ), ) );

$pageone = get_the_permalink($the_query->posts[0]);

echo '<li><a href="'.$pageone.'">'.$category->name.'</a></li>';

endforeach; ?>

Query post or page by specific custom field checkbox value

Will work when querying for pages or by custom post type
<?php
    $args = array(
        'post_type' => 'page',
        'posts_per_page' => -1,
        'post_parent' => 9,
        'order' => 'ASC',
        'orderby' => 'title',
        'meta_query' => array(
            array(
                'key' => 'select_box_option',
                'value' => 'body',
                'compare' => 'LIKE',
            )
        )
     );
$parent = new WP_Query( $args );
if ($parent->have_posts()) : while ($parent->have_posts()) : $parent->the_post(); ?>
    <li><a href="<?php the_permalink(); ?>/"><?php the_title(); ?></a></li>
<?php endwhile; endif; wp_reset_query(); ?>

Create custom link in wp_nav_menu that always links to most recent blog post

// Adds a filter to a nav menu item with link to #latestpost. Will always link to the most recent post
// Front end only, don't hack on the settings page
if ( ! is_admin() ) {
    // Hook in early to modify the menu
    // This is before the CSS "selected" classes are calculated
    add_filter( 'wp_get_nav_menu_items', 'replace_placeholder_nav_menu_item_with_latest_post', 10, 3 );
}

// Replaces a custom URL placeholder with the URL to the latest post function replace_placeholder_nav_menu_item_with_latest_post( $items, $menu, $args ) {

// Loop through the menu items looking for placeholder(s)
foreach ( $items as $item ) {

    // Is this the placeholder we're looking for?
    if ( '#latestpost' != $item-&gt;url )
        continue;

    // Get the latest post
    $latestpost = get_posts( array(
        'numberposts' =&gt; 1,
    ) );

    if ( empty( $latestpost ) )
        continue;

    // Replace the placeholder with the real URL
    $item-&gt;url = get_permalink( $latestpost[0]-&gt;ID );
}

// Return the modified (or maybe unmodified) menu items array
return $items;

}

Pagination for Child Pages

The pages loop from the menu order by ascending values, as seen in the get_pages() function.
<?php
  $pagelist = get_pages("child_of=".$post->post_parent."&parent=".$post->post_parent."&sort_column=menu_order&sort_order=asc");
  $pages = array();
  foreach ($pagelist as $page) {
    $pages[] += $page->ID;
  }

$current = array_search($post->ID, $pages); $prevID = $pages[$current-1]; $nextID = $pages[$current+1]; ?>

<div class="nextprevbutton "> <?php if (!empty($prevID)) { ?> <div class="previous"> <a href="<?php echo get_permalink($prevID); ?>" title="<?php echo get_the_title($prevID); ?>"> < Previous </a>

</div> <?php } if (!empty($nextID)) { ?> <div class="next"> <a href="<?php echo get_permalink($nextID); ?>" title="<?php echo get_the_title($nextID); ?>"> Next > </a> </div> <?php } ?> </div>

Pagination for Blog

<?php if ( have_posts() ) : ?>

<!-- Add the pagination functions here. -->

<!-- Start of the main loop. --> <?php while ( have_posts() ) : the_post(); ?>

<!-- the rest of your theme's main loop -->

<?php endwhile; ?> <!-- End of the main loop -->

<!-- Add the pagination functions here. --> <div class="nextprevbutton"> <div class="nav-previous alignleft"><?php next_posts_link( 'Older posts >' ); ?></div> <div class="nav-next alignright"><?php previous_posts_link( '< Newer posts' ); ?></div>

<?php else : ?> <p><?php _e('Sorry, no posts matched your criteria.'); ?></p> <?php endif; ?>

Create infinite pagination of child pages

This script goes into function.php. When
dbdb_next_page_link()
and
dbdb_prev_page_link()
are called it will create pagination of the child pages you are currently on. Adjust $output to style it as desired
/*----------------------child page navigation--------------------------*/
function relative_value_array($array, $current_val = '', $offset = 1) {
    $values = array_values($array);
    $current_val_index = array_search($current_val, $values); 
    if( isset($values[$current_val_index + $offset]) ) {
        return $values[$current_val_index + $offset];
    }
    return false;
};

function first_array_value($array, $current_val = '', $offset = 1) { $values = array_values($array); if( isset($values[0 + $offset]) ) { return $values[0 + $offset]; } return false; };

function last_array_value($array, $current_val = '', $offset = 1) { $values = array_values($array); if( isset($values[count($array) + $offset]) ) { return $values[count($array) + $offset]; } return false; };

function dbdb_prev_page_link() { global $post; if ( isset($post->post_parent) && $post->post_parent > 0 ) {

    $children = get_pages('&amp;sort_column=post_date&amp;sort_order=asc&amp;child_of='.$post-&gt;post_parent.'&amp;parent='.$post-&gt;post_parent);

};
foreach( $children as $child ) { $child_id_array[] = $child-&gt;ID; }
$prev_page_id = relative_value_array($child_id_array, $post-&gt;ID, -1);
$output = '';
if( '' != $prev_page_id ) {
    $output .= '<a href="' . get_page_link($prev_page_id) . '"> « '. Previous . '</a>';
}
	else {
			$prev_page_id = last_array_value($child_id_array, $post-&gt;ID, -1 );
    $output .= '<a href="' . get_page_link($prev_page_id) . '"> « '. Previous . '</a>';
}
return $output;

}; function dbdb_next_page_link() { global $post; if ( isset($post->post_parent) && $post->post_parent > 0 ) {

    $children = get_pages('&amp;sort_column=post_date&amp;sort_order=asc&amp;child_of='.$post-&gt;post_parent.'&amp;parent='.$post-&gt;post_parent);
};
foreach( $children as $child ) { $child_id_array[] = $child-&gt;ID; }
$next_page_id = relative_value_array($child_id_array, $post-&gt;ID, 1);
$output = '';
if( '' != $next_page_id ) {
    $output .= '<a href="' . get_page_link($next_page_id) . '">'. Next . ' »</a>';
} else{
		$next_page_id = first_array_value($child_id_array, $post-&gt;ID, 0);
 $output .= '<a href="' . get_page_link($next_page_id) . '">'. Next . ' »</a>';
}
return $output;

};

Redirect Parent Page to First Child Page

Goes to the first child by menu order as directed in the get_pages(). Adds a 301 status code to prevent SEO issues.
$pagekids = get_pages("child_of=".$post->ID."&sort_column=menu_order");
if ($pagekids) {
  $firstchild = $pagekids[0];
  wp_redirect(get_permalink($firstchild->ID), 301);
}

Dynamically Load List of Child Pages

Makes an unordered list of child pages. In this code, the list is sorted by menu order.
 <!-- Dynamically load list of services added -->
 <?php
 if ( $post->post_parent ) {
    $children = wp_list_pages( array(
    'title_li' => '',
    'child_of' => $post->post_parent,
    'echo' => 0,
    'sort_column' => 'menu_order'
 ) );
 } 
else {
    $children = wp_list_pages( array(
    'title_li' => '',
    'child_of' => $post->ID,
    'echo' => 0,
    'sort_column' => 'menu_order'
 ) );
 }

if ( $children ) : ?> <ul class="option-list"> <?php echo $children; ?> </ul> <?php endif; ?> <!-- -->

Apply a 'menu_order' filter to Prev/Next links in a post type single.php

Usually the following code will create prev/next links that go to the prev/next post in chronological order
<?php previous_post_link( '%link ','Previous' ); ?>
<?php next_post_link('%link','Next' ); ?>
The following code will apply a meta filter that will prev/next to the correct pages that are sorted by 'menu_order'. You should be able to modify this to order them by other things, such as 'title', as well. Insert the filter before you call the prev/next_post_link functions. You can also search by 'p.post_parent = number' in the query
function my_previous_post_where() {
	global $post, $wpdb;
	return $wpdb->prepare( "WHERE p.menu_order < %s AND p.post_type = %s AND p.post_status = 'publish'", $post->menu_order, $post->post_type);
}
add_filter( 'get_previous_post_where', 'my_previous_post_where' );

function my_next_post_where() { global $post, $wpdb; return $wpdb->prepare( "WHERE p.menu_order > %s AND p.post_type = %s AND p.post_status = 'publish'", $post->menu_order, $post->post_type); } add_filter( 'get_next_post_where', 'my_next_post_where' );

function my_previous_post_sort() { return "ORDER BY p.menu_order desc LIMIT 1"; } add_filter( 'get_previous_post_sort', 'my_previous_post_sort' );

function my_next_post_sort() { return "ORDER BY p.menu_order asc LIMIT 1"; } add_filter( 'get_next_post_sort', 'my_next_post_sort' );

Get alt tag from featured image

 echo get_post_meta(get_post_thumbnail_id($post->ID),'_wp_attachment_image_alt', true);

JS jQuery code

Jquery slide animate to anchor

Handy bit of Jquery code because it uses a smooth animation automatically on page load and also automatically gets the id to scroll to by pulling it from the hash in the URL. Looks like it requires a plugin (jquery.easing.min.js) for that easing option, but any normal easing option can be used instead
var window_hash = window.location.hash;
if(window_hash.length > 0){
   window_hash = window_hash.slice(0,-1);
	$('html, body').stop().animate({
		scrollTop: ($(window_hash).offset().top - 90)
	}, 1250, 'easeInOutExpo');
}

Page Optimization

What server is the domain on?

To find this out go to tools.pingdom.com and enter the domain. Then look into the dropdown on the domain info. In the picture below the Server is Apache.

pingdom-looking-for-server

Leverage Caching

To leverage caching add this script to the top of the .htaccess file
## EXPIRES CACHING ##
<IfModule mod_expires.c>
ExpiresActive On
ExpiresByType image/jpg "access 1 year"
ExpiresByType image/jpeg "access 1 year"
ExpiresByType image/gif "access 1 year"
ExpiresByType image/png "access 1 year"
ExpiresByType text/css "access 1 month"
ExpiresByType text/html "access 1 month"
ExpiresByType application/pdf "access 1 month"
ExpiresByType text/x-javascript "access 1 month"
ExpiresByType application/x-shockwave-flash "access 1 month"
ExpiresByType image/x-icon "access 1 year"
ExpiresDefault "access 1 month"
</IfModule>
## EXPIRES CACHING ##
If that doesn't work try
 <filesMatch ".(ico|pdf|flv|jpg|svg|jpeg|png|gif|js|css|swf)$">
   Header set Cache-Control "max-age=84600, public"
 </filesMatch>
If the domain is on a NGINX Server
location ~* \.(js|css|png|jpg|svg|jpeg|gif|ico)$ {
 expires 2d;
 add_header Cache-Control "public, no-transform";
}
Or if the domain is on ASP.NET Server, look into the ftp files for web.config and add this script
<system.webServer>
 <staticContent>
  <clientCache cacheControlMode="UseMaxAge" cacheControlMaxAge="7.00:00:00" />
 </staticContent>
</system.webServer>

GZIP Compression

Try out the scipts in the .htaccess. First try the next code.
<ifModule mod_gzip.c>
mod_gzip_on Yes
mod_gzip_dechunk Yes
mod_gzip_item_include file .(html?|txt|css|js|php|pl)$
mod_gzip_item_include handler ^cgi-script$
mod_gzip_item_include mime ^text/.*
mod_gzip_item_include mime ^application/x-javascript.*
mod_gzip_item_exclude mime ^image/.*
mod_gzip_item_exclude rspheader ^Content-Encoding:.*gzip.*
</ifModule>
For an Apache Server
## GZIP ##
<IfModule mod_deflate.c>
 # Compress HTML, CSS, JavaScript, Text, XML and fonts
 AddOutputFilterByType DEFLATE application/javascript
 AddOutputFilterByType DEFLATE application/rss+xml
 AddOutputFilterByType DEFLATE application/vnd.ms-fontobject
 AddOutputFilterByType DEFLATE application/x-font
 AddOutputFilterByType DEFLATE application/x-font-opentype
 AddOutputFilterByType DEFLATE application/x-font-otf
 AddOutputFilterByType DEFLATE application/x-font-truetype
 AddOutputFilterByType DEFLATE application/x-font-ttf
 AddOutputFilterByType DEFLATE application/x-javascript
 AddOutputFilterByType DEFLATE application/xhtml+xml
 AddOutputFilterByType DEFLATE application/xml
 AddOutputFilterByType DEFLATE font/opentype
 AddOutputFilterByType DEFLATE font/otf
 AddOutputFilterByType DEFLATE font/ttf
 AddOutputFilterByType DEFLATE image/svg+xml
 AddOutputFilterByType DEFLATE image/x-icon
 AddOutputFilterByType DEFLATE text/css
 AddOutputFilterByType DEFLATE text/html
 AddOutputFilterByType DEFLATE text/javascript
 AddOutputFilterByType DEFLATE text/plain
 AddOutputFilterByType DEFLATE text/xml

Remove browser bugs (only needed for really old browsers)

BrowserMatch ^Mozilla/4 gzip-only-text/html BrowserMatch ^Mozilla/4.0[678] no-gzip BrowserMatch \bMSIE !no-gzip !gzip-only-text/html Header append Vary User-Agent </IfModule>

GZIP ##

For NGINX Server, you can enable compression by adding the following to your nginx.conf file.

gzip on;
gzip_comp_level 2;
gzip_http_version 1.0;
gzip_proxied any;
gzip_min_length 1100;
gzip_buffers 16 8k;
gzip_types text/plain text/html text/css application/x-javascript text/xml application/xml application/xml+rss text/javascript;
gzip_disable "MSIE [1-6].(?!.*SV1)";
gzip_vary on;

Here is the full example web.config file

<?xml version="1.0"?>
<configuration>

 <system.web>
   <compilation debug="true" targetFramework="4.0"/>
 </system.web>
 
 <system.webServer>
   <httpErrors errorMode="Custom">
     <clear/>
     <error statusCode="404" path="404.html" responseMode="Redirect"/>
   </httpErrors>
 </system.webServer>
 
 <system.webServer>
    <staticContent>
      <clientCache cacheControlMode="UseMaxAge" cacheControlMaxAge="7.00:00:00" />
    </staticContent>
 </system.webServer>
 
</configuration>

Remove Query String From Static Resources

Enter at the end of functions.php in your WordPress files.
/*** Remove Query String from Static Resources ***/
function _remove_script_version( $src ){
 $parts = explode( '?ver', $src );
 return $parts[0];
}
add_filter( 'script_loader_src', '_remove_script_version', 15, 1 );
add_filter( 'style_loader_src', '_remove_script_version', 15, 1 );

Parallelize Downloads Across Hostnames

First try to minify and combine javascript and css files first before trying out this script. Add code to the end of functions.php , read the comments of the code as well, there are instructions.
// Parallelize downloads across hostnames

function parallelize_hostnames($url, $id) { $hostname = par_get_hostname($url); //call supplemental function $url = str_replace(parse_url(get_bloginfo('url'), PHP_URL_HOST), $hostname, $url); return $url; } function par_get_hostname($name) { //add your subdomains here, as many as you want. ********** CHANGE DOMAIN ********** $subdomains = array('media1.mydomain.com','media2.mydomain.com'); $host = abs(crc32(basename($name)) % count($subdomains)); $hostname = $subdomains[$host]; return $hostname; } add_filter('wp_get_attachment_url', 'parallelize_hostnames', 10, 2);

Moving scripts to the footer

SEO

Making a 5 star review link for Google

Get google maps link.
https://www.google.com/maps/place/Dr.+Julie+Phillips+Prosthodontics/
Grab the search query (text with plus signs)
Dr.+Julie+Phillips+Prosthodontics
"View Source" of the Google Maps page and search for "ludocid" (Ctrl-F) on the source code. Here is an example what you will find.
ludocid\\u003d10332763409006310141 #lrd\\u003d0x88531ed2d17eac7b: 0x8f6559933df9b2fd,2 ludocid number is after the "d" = ("10332763409006310141") lrd number is the same, but nothing after the comma =("0x88531ed2d17eac7b:0x8f6559933df9b2fd")
Add your numbers into the new search query url
https://www.google.com/search?q=(Add the search text here)&ludocid=(ludocid number here)#lrd=(lrd number here),3,5
The url will now look like this, and a five star review will populate the page.
https://www.google.com/search?q=Dr.+Julie+Phillips+Prosthodontics&  ludocid=10332763409006310141# lrd=0x88531ed2d17eac7b: 0x8f6559933df9b2fd,3,5

SEO Issues

Canonical Link issue. Two pages that are from the same page with different links. Add this link tag inside "head" tag before the <link rel="stylesheet" />
<link rel="canonical" href="http://example.com/" />
 

Add Event Tracking for Google Analytics

Add the following script to the header file.

<script> var trackOutboundLink = function(url) { ga('send', 'event', 'outbound', 'click', url, { 'transport': 'beacon' }); } </script>

 

Now add the following code to each a tag or link and label them appropriately

onclick="trackOutboundLink('Request-an-appointment-header');"

 

Remember to label the even appropriately, if it is linking to Facebook in the header section of the website an example is:

<a href="https://www.facebook.com/Athena-Skin-Body-1840833106242156/" target="_blank" onclick="trackOutboundLink('facebook-header');">Facebook</a>

<?php function add_this_script_footer(){ ?>

<script src="<?php bloginfo('template_directory'); ?>/script.js"></script> <!-- bootstap, script, lightslider -->

<?php } add_action('wp_footer', 'add_this_script_footer'); ?>

WP Plugins

Above the Fold Optimization

https://wordpress.org/plugins/above-the-fold-optimization/

CSS/JS delivery optimization. Will provide async loading of certain resources to help prevent render-blocking files from blocking content.

Advanced Excerpt

https://wordpress.org/plugins/advanced-excerpt/

Easy controls for blog index page excerpts. Preserves HTML tags like images and iframes and cuts off blog posts when they reach a certain number of characters/words to keep index pages from getting too long. Can add and edit a "Read More" link.

Found a bit of code that disables the "Read More" link if the post isn't actually excerpted (short enough to just display the whole thing). Go into the plugin editor to the advanced-excerpt/functions/functions.php file and paste into the very bottom:

function ca_only_add_more_when_required( $default, $text, $options ) {
 $text = strip_tags( $text );
 if ( 'words' === $options['length_type'] ) {
 $excerpt_length = str_word_count( $text );
 } else {
 $excerpt_length = strlen( $text );
 }
 if ( $excerpt_length > $options['length'] ) return $default;
 return true;
}
add_filter( 'advanced_excerpt_disable_add_more', 'ca_only_add_more_when_required', 10, 3 );

About

A poorly organized collection of Wordpress notes and code

Topics

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published