All posts by acrane

About acrane

A web designer from Charlotte, NC, I enjoy working in the yard, kayaking, building stuff, making things, creating, thinking and of course WordPress.

Helpful webdesign links

Hex to RGB converter. This helps for putting the opacity on the background color instead of the div. That way your text inside doesn’t inherit the opacity.

http://hex.colorrrs.com/

So, if you have a rgb color like:

.main-navigation a.learn {
	background-color: rgb(255,0,255);
}

you can add an “a” to the rgb and get your Alpha, or opacity:

.main-navigation a.learn {
	background-color: rgba(255,0,255, 0.85);
}

 

CSS Box shadow generator: Where have you been all my life! Huge time saver.

http://www.cssmatic.com/box-shadow

Overlapping images using Isotope jQuery

There are several ways to fix overlapping images when using isotope. The problem comes when the isotope event triggers before the images sizes, font sizes and other divs are not yet known. Isotope’s own faq’s tells you how to fix this with their layout method. But it also depends on how you’re calling your jQuery, and your functions. Working with WordPress, I usually put all my custom jQuery functions in a file and load them with

$(document).ready(function () {
   // everything here
});

But if you’re using isotope layout method, the only thing I’ve found to work is:

$(window).load(function () {
   // everything here
});

 

Adding extra fields to Woocommerce checkout and applying them to the email

How to add extra fields to the Woocommerce Checkout page and have those values get sent in the order email.

This expands on a tutorial here.

We will be adding two extra checkout fields, “Student’s Name” and “Teacher’s” Name, both text inputs. First we create the fields, then save them. We will also show them in the order in the dashboard as well as send the info through the new order email.

The first function creates the field. Put all of these in your theme’s functions file.

/**
 * Add the field to the checkout
 */
add_action( 'woocommerce_after_order_notes', 'my_custom_checkout_field' );

function my_custom_checkout_field( $checkout ) {

    echo '<div id="my_custom_checkout_field"><h2>' . __('School Info') . '</h2>';

    woocommerce_form_field( 'student_name', array(
        'type'          => 'text',
        'class'         => array('my-field-class form-row-wide'),
        'label'         => __('Student\'s Name' . ' <abbr class="required" title="required">*</abbr>'),
        'placeholder'   => __('Name'),
        ), $checkout->get_value( 'student_name' ));
		
		
	woocommerce_form_field( 'student_teacher', array(
        'type'          => 'text',
        'class'         => array('my-field-class form-row-wide'),
        'label'         => __('Student\'s Teacher' . ' <abbr class="required" title="required">*</abbr>'),
        'placeholder'   => __('Teacher\'s Name'),
        ), $checkout->get_value( 'student_teacher' ));

    echo '</div>';
} //

Next we process the fields when we submit and check to see if they’re required. In this case, we will require them:

/**
 * Process the checkout
 */
add_action('woocommerce_checkout_process', 'my_custom_checkout_field_process');

function my_custom_checkout_field_process() {
    // Check if set, if its not set add an error.
    if ( ! $_POST['student_name'] )
        wc_add_notice( __( '<strong>Student\'s name</strong> is a required field.' ), 'error' );
	if ( ! $_POST['student_teacher'] )
        wc_add_notice( __( '<strong>Teachers\'s name</strong> is a required field.' ), 'error' );
	} //

Next we save the values, if not empty, to the orders meta:

/**
 * Update the order meta with field value
 */
add_action( 'woocommerce_checkout_update_order_meta', 'my_custom_checkout_field_update_order_meta' );

function my_custom_checkout_field_update_order_meta( $order_id ) {
    if ( ! empty( $_POST['student_name'] ) ) {
        update_post_meta( $order_id, 'Student Name', sanitize_text_field( $_POST['student_name'] ) );
    }
	if ( ! empty( $_POST['student_teacher'] ) ) {
        update_post_meta( $order_id, 'Teacher Name', sanitize_text_field( $_POST['student_teacher'] ) );
    }
}

This function will display the values on the order edit page in the backend under orders:

/**
 * Display field value on the order edit page
 */
add_action( 'woocommerce_admin_order_data_after_billing_address', 'my_custom_checkout_field_display_admin_order_meta', 10, 1 );

function my_custom_checkout_field_display_admin_order_meta($order){
    echo '<p><strong>'.__('Student Name').':</strong> ' . get_post_meta( $order->id, 'Student Name', true ) . '</p>';
	 echo '<p><strong>'.__('Teacher Name').':</strong> ' . get_post_meta( $order->id, 'Teacher Name', true ) . '</p>';
}

 

/**
 * Display field value on the order edit page
 */
add_action( 'woocommerce_admin_order_data_after_billing_address', 'my_custom_checkout_field_display_admin_order_meta', 10, 1 );

function my_custom_checkout_field_display_admin_order_meta($order){
    echo '<p><strong>'.__('Student Name').':</strong> ' . get_post_meta( $order->id, 'Student Name', true ) . '</p>';
	 echo '<p><strong>'.__('Teacher Name').':</strong> ' . get_post_meta( $order->id, 'Teacher Name', true ) . '</p>';
}

Lastly we can send the values out through the email. There are a number of emails to choose from. We will choose the on located here: Dashboard > Woocommerce > Settings > Emails (tab) > New Order. At the bottom of this page, you can see the html email template. Open that up and place the following in that file.

<?php if ( get_post_meta( $order->id, 'Student Name', true ) ) : ?>
	<p><strong><?php _e( 'Student\'s Name:', 'woocommerce' ); ?></strong> <?php echo get_post_meta( $order->id, 'Student Name', true ) ?></p>
<?php endif; ?>

<?php if ( get_post_meta( $order->id, 'Teacher Name', true ) ) : ?>
	<p><strong><?php _e( 'Teacher\'s Name:', 'woocommerce' ); ?></strong> <?php echo get_post_meta( $order->id, 'Teacher Name', true ) ?></p>
<?php endif; ?>

 

Custom Post Type Slider Flexslider with Advanced Custom Fields

Place the following in your functions file or theme plugin:

It will register your post type, “slides”, and enqueue your javascripts, “jquery”, “custom” and “flexslider” that can be found further down.

 // Enqueueing all the java script in a no conflict mode
 function ineedmyjava() {
	if (!is_admin()) {
 
		wp_deregister_script('jquery');
		wp_register_script('jquery', 'http://ajax.googleapis.com/ajax/libs/jquery/1.10.2/jquery.min.js', false, '1.10.2', true);
		wp_enqueue_script('jquery');
		
		// Custom Theme scripts...
		wp_register_script(
			'custom',
			get_bloginfo('template_directory') . '/js/custom.js',
			array('jquery') );
		wp_enqueue_script('custom');
		
		
		// Homepage slider 'flexslider' scripts...
		wp_register_script(
			'flexslider',
			get_bloginfo('template_directory') . '/js/flexslider.js',
			array('jquery') );
		wp_enqueue_script('flexslider');
		
	}
}
 
add_action('wp_enqueue_scripts', 'ineedmyjava');


/* Custom Post Types */

add_action('init', 'js_custom_init');
function js_custom_init() 
{
   // Register the Slides Custom Post Type
  
     $labels = array(
	'name' => _x('Slides', 'post type general name'),
    'singular_name' => _x('Slide', 'post type singular name'),
    'add_new' => _x('Add New', 'Slide'),
    'add_new_item' => __('Add New Slide'),
    'edit_item' => __('Edit Slides'),
    'new_item' => __('New Slide'),
    'view_item' => __('View Slides'),
    'search_items' => __('Search Slides'),
    'not_found' =>  __('No Slides found'),
    'not_found_in_trash' => __('No Slides found in Trash'), 
    'parent_item_colon' => '',
    'menu_name' => 'Slides'
  );
  $args = array(
	'labels' => $labels,
    'public' => true,
    'publicly_queryable' => true,
    'show_ui' => true, 
    'show_in_menu' => true, 
    'query_var' => true,
    'rewrite' => true,
    'capability_type' => 'post',
    'has_archive' => false, 
    'hierarchical' => false,
    'menu_position' => 20,
    'supports' => array('title','editor','custom-fields','thumbnail'),
	
  ); 
  register_post_type('slides',$args);
  
  } // close custom post type

These are the javascript files you need to include in a folder, “js” in you theme. The other points to google’s hosted version.
Custom.js

flexslider.js
Flexslider.js

In a theme file, where ever…
This Custom Post Type includes the Advanced Custom Fields Plugin to use an image uploader, set to “image url”. This is in it’s simplest form. You can add more Custom Fields if you like and add them between the list item.

<?php 
// Query the Post type Slides
$querySlides = array(
	'post_type' => 'slides',
);
// The Query
$the_query = new WP_Query( $querySlides );
?>
<?php 
// The Loop
 if ( $the_query->have_posts()) : ?>

<div class="flexslider">
        <ul class="slides">
        <?php while ( $the_query->have_posts() ) : ?>
			<?php $the_query->the_post(); ?>
            
            <li> 
                <div class="banner">
                <?php if(get_field('slide_image')!="") { ?>
                		<img src="<?php the_field('slide_image'); ?>" />
                  <?php } ?>
                </div><!-- home banner pic -->
            </li>
            
           <?php endwhile; ?>
      	 </ul><!-- slides -->
</div><!-- .flexslider -->
         <?php endif; // end loop ?>
        
    <?php wp_reset_postdata(); ?>

 

Finally, some css to get started.

/* Browser Resets
*********************************/
.flex-container a:active,
.flexslider a:active,
.flex-container a:focus,
.flexslider a:focus  {outline: none;}
.slides,
.flex-control-nav,
.flex-direction-nav {margin: 0; padding: 0; list-style: none;}

/* Icon Fonts
*********************************/
/* Font-face Icons */
@font-face {
	font-family: 'flexslider-icon';
	src:url('fonts/flexslider-icon.eot');
	src:url('fonts/flexslider-icon.eot?#iefix') format('embedded-opentype'),
		url('fonts/flexslider-icon.woff') format('woff'),
		url('fonts/flexslider-icon.ttf') format('truetype'),
		url('fonts/flexslider-icon.svg#flexslider-icon') format('svg');
	font-weight: normal;
	font-style: normal;;
}

/* FlexSlider Necessary Styles
*********************************/
.flexslider {
    margin: 0;
    padding: 0;
}

.flexslider .slides > li {
    display: none;
    -webkit-backface-visibility: hidden;
} /* Hide the slides before the JS is loaded. Avoids image jumping */
.flexslider .slides img {
    width: 100%;
    display: block;
}

.flex-pauseplay span {
    text-transform: capitalize;
}

/* Clearfix for the .slides element */
.slides:after {
    content: "\0020";
    display: block;
    clear: both;
    visibility: hidden;
    line-height: 0;
    height: 0;
}

html[xmlns] .slides {
    display: block;
}

* html .slides {
    height: 1%;
}

/* No JavaScript Fallback */
/* If you are not using another script, such as Modernizr, make sure you
 * include js that eliminates this class on page load */
.no-js .slides > li:first-child {
    display: block;
}

/* FlexSlider Default Theme
*********************************/
.flexslider {
    /*margin: 0 0 60px;
    background: #fff;
    border: 4px solid #fff;*/
    position: relative;
  /*  -webkit-border-radius: 4px;
    -moz-border-radius: 4px;
    -o-border-radius: 4px;
    border-radius: 4px;
    -webkit-box-shadow: 0 1px 4px rgba(0,0,0,.2);
    -moz-box-shadow: 0 1px 4px rgba(0,0,0,.2);
    -o-box-shadow: 0 1px 4px rgba(0,0,0,.2);
    box-shadow: 0 1px 4px rgba(0,0,0,.2);
    zoom: 1;*/
}

.flex-viewport {
    max-height: 2000px;
    -webkit-transition: all 1s ease;
    -moz-transition: all 1s ease;
    -o-transition: all 1s ease;
    transition: all 1s ease;
}

.loading .flex-viewport {
    max-height: 300px;
}

.flexslider .slides {
    zoom: 1;
}

.carousel li {
    margin-right: 5px;
}

/* Direction Nav */
.flex-direction-nav {
    *height: 0;
}

.flex-direction-nav a {
    display: block;
    width: 40px;
    height: 40px;
    margin: -20px 0 0;
    position: absolute;
    top: 50%;
    z-index: 10;
    overflow: hidden;
    opacity: 0;
    cursor: pointer;
    color: rgba(0,0,0,0.8);
    text-shadow: 1px 1px 0 rgba(255,255,255,0.3);
    -webkit-transition: all .3s ease;
    -moz-transition: all .3s ease;
    transition: all .3s ease;
}

.flex-direction-nav .flex-prev {
  /*  left: -50px;*/
	   left: 10px;
	    opacity: 0.7;
}

.flex-direction-nav .flex-next {
    /*right: -50px;*/
	right: 10px;
    text-align: right;
	 opacity: 0.7;
}

.flexslider:hover .flex-prev {
    opacity: 0.7;
    left: 10px;
}

.flexslider:hover .flex-next {
    opacity: 0.7;
    right: 10px;
	z-index: 1000;
}

.flexslider:hover .flex-next:hover, .flexslider:hover .flex-prev:hover {
    opacity: 1;
}

.flex-direction-nav .flex-disabled {
    opacity: 0!important;
    filter: alpha(opacity=0);
    cursor: default;
}

.flex-direction-nav a:before {
    font-family: "flexslider-icon";
    font-size: 40px;
    display: inline-block;
    content: '\f001';
}

.flex-direction-nav a.flex-next:before {
    content: '\f002';
}

/* Pause/Play */
.flex-pauseplay a {
    display: block;
    width: 20px;
    height: 20px;
    position: absolute;
    bottom: 5px;
    left: 10px;
    opacity: 0.8;
    z-index: 10;
    overflow: hidden;
    cursor: pointer;
    color: #000;
}

.flex-pauseplay a:before {
    font-family: "flexslider-icon";
    font-size: 20px;
    display: inline-block;
    content: '\f004';
}

.flex-pauseplay a:hover {
    opacity: 1;
}

.flex-pauseplay a.flex-play:before {
    content: '\f003';
}

/* Control Nav */
.flex-control-nav {
    width: 100%;
    position: absolute;
    bottom: -20px;
    text-align: center;
}

.flex-control-nav li {
    margin: 0 6px;
    display: inline-block;
    zoom: 1;
    *display: inline;
}

.flex-control-paging li a {
    width: 11px;
    height: 11px;
    display: block;
    background: #666;
    background: rgba(0,0,0,0.5);
    cursor: pointer;
    text-indent: -9999px;
    -webkit-border-radius: 20px;
    -moz-border-radius: 20px;
    -o-border-radius: 20px;
    border-radius: 20px;
    -webkit-box-shadow: inset 0 0 3px rgba(0,0,0,0.3);
    -moz-box-shadow: inset 0 0 3px rgba(0,0,0,0.3);
    -o-box-shadow: inset 0 0 3px rgba(0,0,0,0.3);
    box-shadow: inset 0 0 3px rgba(0,0,0,0.3);
}

.flex-control-paging li a:hover {
    background: #333;
    background: rgba(0,0,0,0.7);
}

.flex-control-paging li a.flex-active {
    background: #000;
    background: rgba(0,0,0,0.9);
    cursor: default;
}

.flex-control-thumbs {
    margin: 5px 0 0;
    position: static;
    overflow: hidden;
}

.flex-control-thumbs li {
    width: 25%;
    float: left;
    margin: 0;
}

.flex-control-thumbs img {
    width: 100%;
    display: block;
    opacity: .7;
    cursor: pointer;
}

.flex-control-thumbs img:hover {
    opacity: 1;
}

.flex-control-thumbs .flex-active {
    opacity: 1;
    cursor: default;
}

@media screen and (max-width: 860px) {
    .flex-direction-nav .flex-prev {
        opacity: 1;
        left: 10px;
    }

    .flex-direction-nav .flex-next {
        opacity: 1;
        right: 10px;
    }
}

How to keep spam off wordpress image attachments by not allowing comments on them

How to keep spam off wordpress image attachments by not allowing comments on them.

Place the following in your theme’s functions.php file.

add_filter( 'comments_open', 'no_media_comments', 10, 2 );

function no_media_comments( $open, $post_id ) {

	$post = get_post( $post_id );
        // wordpress refers to images as attachments
	if ( 'attachment' == $post-&gt;post_type )
		$open = false;

	return $open;
}

 

ACF Repeater with Image Object starter code to get movin quick

Some code to get started with a repeater that has an Image ACF that pulls the image object.

<?php if( have_rows('repeater_field_name') ): ?>
	<?php while ( have_rows('repeater_field_name') ) : ?>
	<?php the_row(); ?>
 
	 <?php 
        // Get field Name
        $image = get_sub_field('picture'); 
        $url = $image['url'];
        $title = $image['title'];
        $alt = $image['alt'];
        $caption = $image['caption'];
     
        // size or custom size that will go
        // into the "thumb" variable.
        $size = 'large';
        $thumb = $image['sizes'][ $size ];
        $width = $image['sizes'][ $size . '-width' ];
        $height = $image['sizes'][ $size . '-height' ];
        ?>
        
        <img src="<?php echo $thumb; ?>" alt="<?php echo $alt; ?>" title="<?php echo $title; ?>" />
        
       	<?php  the_sub_field('sub_field_name'); ?>
       
   <?php endwhile; ?>
<?php endif; ?>

 

Password Protect WordPress ACF and other parts of the page.

WordPress allows you to password protect the_content() by default, that’s easy. Here is how to password protect certain parts of the page or Advanced Custom Fields.

Example includes the protected area and the form to access the protected area.

<h1>Members Section</h1>  
         
<?php if ( post_password_required() ) : ?>   
<form method="post" action="<?php bloginfo('wpurl'); ?>/wp-login.php?action=postpass">
        <p>This content is password protected. To view it please enter your password below:</p>
        <input type="password" style="margin:10px 0;" size="20" id="pwbox-<?php the_ID(); ?>" name="post_password"/></label><br/>
        <input type="submit" value="Submit" name="Submit"/></p>
    </form> 
<?php endif; ?>
    
<?php
// password protect Members section fields
if ( !post_password_required() ) { ?>
    <div class="entry-content">
        <?php the_field('page_content'); ?>
    </div><!-- entry content -->
<?php } ?>

 

How to create a Custom WordPress Lightbox or Colorbox

This tutorial will show you how to create a completely custom  jQuery WordPress Lightbox or Colorbox that can include photo groups, custom html, custom html groups and will allow you to use the WordPress loop to make it even cooler.

It will be using the jQuery plugin, “Colorbox”, which you can get and read about here > http://www.jacklmoore.com/colorbox/

Download the jQuery script jquery.colorbox-min.js and put it in your theme’s “js” folder. Also create a “custom.js” and put it in your theme’s “js” folder.

Enqueue the 2 scripts in your themes function file. Example

 // Enqueueing all the java script in a no conflict mode
 function ineedmyjava() {
	if (!is_admin()) {
 
		wp_deregister_script('jquery');
		wp_register_script('jquery', 'http://ajax.googleapis.com/ajax/libs/jquery/1.10.2/jquery.min.js', false, '1.10.2', true);
		wp_enqueue_script('jquery');
		
		// Custom Theme scripts...
		wp_register_script(
			'custom',
			get_bloginfo('template_directory') . '/js/custom.js',
			array('jquery') );
		wp_enqueue_script('custom');
		
		
		// Lightbox/Colorbox scripts...
		wp_register_script(
			'colorbox',
			get_bloginfo('template_directory') . '/js/jquery.colorbox-min.js',
			array('jquery') );
		wp_enqueue_script('colorbox');
		
		// Add more
		
		
		// between here
		
	}
}
 
add_action('init', 'ineedmyjava');

Link the default colorbox.css file into your theme. You’ll also want to put in the images that come with it in your images folder.

It should all be working now. Here is an example of the simplest form of this plugin. The a class”inline” matches the script in your custom.js file, just like the one you downloaded above.

<p><a class='inline' href="#inline_content">Open me</a></p>

<!-- This contains the hidden content for inline calls -->
		<div style='display:none'>
			<div id='inline_content' style='padding:10px; background:#fff;'>
                <h1>Hello</h1>
                <p>Some Text</p>
			</div>
		</div>

 How to do inside of a WordPress loop.

Your Loop

<?php 
/*
 		You have to set a variable for your 
		divs to open the right hidden div. 
*/
// put the name of the post type title into "divLink"
$divLink = get_the_title();

/* We will throw the variable into the function 
	of sanitize title with dashes to make it friendly
	that will open all the right divs
*/ 
?>

<div class="openme">
	<a href="#<?php echo sanitize_title_with_dashes($divLink); ?>" class="group-name">
</div><!-- open me -->

<!-- This contains the hidden content for inline calls -->
<div style='display:none'>
	<div id='<?php echo sanitize_title_with_dashes($divLink); ?>' style='padding:10px; background:#fff;'>
        <h1><?php the_title(); ?></h1>
        <p><?php the_content(); ?></p>
	</div>
</div><!-- display None -->

End your loop

In this Example, you sanitize your titles to be included in your divs so that the correct link will open the  correct hidden div for the lightbox. Your a class of “group-name” changed from the first example and needs to match the jQuery script in your custom.js file.

That would look like this now:
The inline: true allows for html in the lightbox, the width is the width on your screen the lightbox will open.

$(".group-name").colorbox({
	inline:true, 
        width:"50%"
});

This is important because you could set up multiple groups that will allow you to click next while staying in the lightbox.

Multiple Group Example 

First you would have to add a group to your custom.js file. So it might look like this:

$(".group-one").colorbox({
	inline:true, 
	width:"50%",
	rel:'group-one',
	slideshow:false
});
	
$(".group-two").colorbox({
	inline:true, 
	width:"50%",
	rel:'group-two',
	slideshow:false
});

Then you could set up two loops where you could click through all the things in lightbox in the first loop, close it and click on another item that came from another loop and be able to click through those without mixing the two. So that might look like this:

<?php 
// the query
$args = array(
	'post_type' => 'post',
	'posts_per_page' => 3,
	'category_name' => 'news',
);
$the_query = new WP_Query( $args ); ?>
<?php if ( $the_query->have_posts() ) : ?>
<?php while ( $the_query->have_posts() ) : $the_query->the_post(); ?>

<?php 
// put the name of the post type into "divLink"
$divLinkOne = get_the_title();
 
?>

<div class="openme">
	<a href="#<?php echo sanitize_title_with_dashes($divLinkOne); ?>" class="group-one">
    	<?php the_title(); ?>
    </a>
</div><!-- open me -->

<!-- This contains the hidden content for inline calls -->
<div style='display:none'>
	<div id='<?php echo sanitize_title_with_dashes($divLinkOne); ?>' style='padding:10px; background:#fff;'>
        <h1><?php the_title(); ?></h1>
        <p><?php the_content(); ?></p>
	</div>
</div><!-- display None -->

<?php endwhile; ?>
<?php endif; ?>
<?php wp_reset_postdata(); ?>



<?php 
/*
		Second Loop and Second Group

*/
// the query
$args = array(
	'post_type' => 'post',
	'posts_per_page' => 3,
	'category_name' => 'events',
);
$the_query = new WP_Query( $args ); ?>
<?php if ( $the_query->have_posts() ) : ?>
<?php while ( $the_query->have_posts() ) : $the_query->the_post(); ?>

<?php 
// put the name of the post type into "divLink"
$divLinkTwo = get_the_title();
 
?>

<div class="openme">
	<a href="#<?php echo sanitize_title_with_dashes($divLinkTwo); ?>" class="group-two">
    	<?php the_title(); ?>
    </a>
</div><!-- open me -->

<!-- This contains the hidden content for inline calls -->
<div style='display:none'>
	<div id='<?php echo sanitize_title_with_dashes($divLinkTwo); ?>' style='padding:10px; background:#fff;'>
        <h1><?php the_title(); ?></h1>
        <p><?php the_content(); ?></p>
	</div>
</div><!-- display None -->

<?php endwhile; ?>
<?php endif; ?>