Sensible script enqueuing for shortcodes

If you are making a WordPress plugin which uses a shortcode, and said shortcode needs some Javascript enqueued in order to function, it may be tempting to just whack the script in the wp_enqueue_scripts hook and be done with it.

add_action( 'wp_enqueue_scripts', 'enqueue_my_script' );

function enqueue_my_script() {
wp_enqueue_script( 'script-name', plugins_url( '/js/script.js' , __FILE__ ), array(), '1.0.0', false );
}

Yes this works fine, and is perfectly fine during development, but as the script gets loaded site wide this can be terribly inefficient if the script is specific to your plugin.

To improve matters, you can employ some conditional tags to control where your script gets loaded. For example:

add_action( 'wp_enqueue_scripts', 'enqueue_my_script' );

function enqueue_my_script() {
if ( is_archive() || is_single() ) {
wp_enqueue_script( 'script-name', plugins_url( '/js/script.js' , __FILE__ ), array(), '1.0.0', false );
}
}

The above code would enqueue on single posts and within post archives.

For a shortcode however, this can be tricky; you know the shortcode can only be used within posts and pages, but a) thats pretty much site wide anyway and b) you don’t know if the shortcode is being used on the page you are enqueuing the script.

One way you can further optimise your enqueue would be to check the content of a post and see if it contains your code – but again, the drawback is that will most likely only work in certain situations, for example if your shortcode is intended to be used when viewing single posts only.

The sensible method

Forget conditional tags. Forget enqueuing site wide. Instead the solution is quite simple…

First, register your script early, don’t enqueue it.

add_action( 'wp_enqueue_scripts', 'register_my_script' );

function register_my_script() {
wp_register_script( 'script-name', plugins_url( '/js/script.js' , __FILE__ ), array(), '1.0.0', true );
}

At this point, WordPress is aware your script exists, but it won’t be loaded onto pages. Notice the ‘true’ in your wp_register_script call – this is important and tells WP that you want the script to be loaded in the footer of your page.

Next, and this is the best part, you can enqueue on demand. Now in your plugin where you render your shortcode simply add:

wp_enqueue_script( 'script-name' );

This will enqueue your previously registered script ready for output in the footer of the page.

Now you have a lazy-loaded script, and no need for fancy conditional rules – much better.

A New Job Board Plugin for WordPress

job

I’ve just made a new plugin available (on github) that I’ve been working on to allow you to add and manage job listings on your WP site. It’s name; WP Job Manager.

Features

One of the shortcode options for job display
One of the shortcode options for job display
  • Allows admin to create job listings
  • Frontend submission form supporting guests and registered users
  • Jobs can be set to expire after X days
  • Ajaxified job listing shortcode with search, filters and pagination
  • “Overview” shortcode
  • Widgets for showing jobs in your sidebar
  • Jobs can be ‘applied’ for via a munged email address or a given URL (revealed on click)
  • (should) work with any theme given some style love
  • Manage jobs from admin, including approving jobs if required
  • Employer dashboard for marking jobs filled or ending listings early
  • RSS feeds for the currently viewed search

Read on for a more in-depth look at what this baby can do.

Continue reading “A New Job Board Plugin for WordPress”

The New WordPress Download Monitor Plugin

A few months back I announced that the Download Monitor plugin was no longer being maintained. Why? Several reasons really:

  1. Dealing with daily support emails caused a massive headache
  2. Some of the code was embarrassing, and the plugin badly needed a rewrite..
  3. ..but due to legacy this would have been messy and difficult
  4. The donation model didn’t really work, and .org would’t allow ads inside the plugin to fund development

However, despite all of this, given the popularity of the plugin I decided to secretly start building a new version without the restraints of legacy code dictating the way forward…

Continue reading “The New WordPress Download Monitor Plugin”

add_menu_page supports decimal positions

When adding top level menu pages to WordPress admin (using add_menu_page) more often or not you’ll end up conflicting with other plugins. When two plugins share the same menu position, one is not shown:

WARNING: if 2 menu items use the same position attribute, one of the items may be overwritten so that only one item displays!

Since there are a limited number of integer positions in the menu this could be a problem, however, handily WordPress actually supports decimal positions. In this example I’m using ‘55.5’ instead of 55. This should reduce the risk of conflict significantly:

$main_page = add_menu_page(__('WooCommerce', 'woocommerce'), __('WooCommerce', 'woocommerce'), 'manage_woocommerce', 'woocommerce' , 'woocommerce_settings_page', null, '55.5' );

Note that the codex and the source state that integers should be used, even though the decimals do work. Kudos to Gary Jones for pointing this trick out.

Debugging with WP_DEBUG_LOG

The constant WP_DEBUG_LOG is something I’ve only recently discovered — when added to wp-config.php it enables a log of WordPress errors and notices to be saved to wp-content/debug.log.

define( WP_DEBUG_LOG, true );

This is very handy when debugging plugin errors, especially hidden ones like those which occur on plugin activation.

WooCommerce: Output a printable list of processing orders

screen-capture

Someone requested a way to print out a list of their processing orders for WooCommerce so I came up with a snippet to do so 🙂

The code below can be added as a page template in your theme. Once added to your template, just create a page in WordPress admin and assign it the “Print processing orders” page template.

Theres a check at the top of the page to only let admin users in, and when viewed the page will give you a nice list of processing orders which you can then print out.


<?php
/*
Template Name: Print Processing Orders 🙂
*/
if (!is_user_logged_in() || !current_user_can('manage_options')) wp_die('This page is private.');
?>
<!DOCTYPE HTML>
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
<title><?php _e('Processing Orders'); ?></title>
<style>
body { background:white; color:black; width: 95%; margin: 0 auto; }
table { border: 1px solid #000; width: 100%; }
table td, table th { border: 1px solid #000; padding: 6px; }
article { border-top: 2px dashed #000; padding: 20px 0; }
</style>
</head>
<body>
<header>
<?php if (have_posts()) : while (have_posts()) : the_post(); ?>
<h1 class="title"><?php the_title(); ?></h1>
<?php the_content(); ?>
<?php endwhile; endif; ?>
</header>
<section>
<?php
global $woocommerce;
$args = array(
'post_type' => 'shop_order',
'post_status' => 'publish',
'posts_per_page' => –1,
'tax_query' => array(
array(
'taxonomy' => 'shop_order_status',
'field' => 'slug',
'terms' => array('processing')
)
)
);
$loop = new WP_Query( $args );
while ( $loop->have_posts() ) : $loop->the_post();
$order_id = $loop->post->ID;
$order = new WC_Order($order_id);
?>
<article>
<header>
<h2>Order #<?php echo $order_id; ?> &mdash; <time datetime="<?php the_time('c'); ?>"><?php echo the_time('d/m/Y'); ?></time></h2>
</header>
<table cellspacing="0" cellpadding="2">
<thead>
<tr>
<th scope="col" style="text-align:left;"><?php _e('Product', 'woothemes'); ?></th>
<th scope="col" style="text-align:left;"><?php _e('Quantity', 'woothemes'); ?></th>
<th scope="col" style="text-align:left;"><?php _e('Price', 'woothemes'); ?></th>
</tr>
</thead>
<tfoot>
<tr>
<th scope="row" colspan="2" style="text-align:left; padding-top: 12px;"><?php _e('Subtotal:', 'woothemes'); ?></th>
<td style="text-align:left; padding-top: 12px;"><?php echo $order->get_subtotal_to_display(); ?></td>
</tr>
<?php if ($order->order_shipping > 0) : ?><tr>
<th scope="row" colspan="2" style="text-align:left;"><?php _e('Shipping:', 'woothemes'); ?></th>
<td style="text-align:left;"><?php echo $order->get_shipping_to_display(); ?></td>
</tr><?php endif; ?>
<?php if ($order->order_discount > 0) : ?><tr>
<th scope="row" colspan="2" style="text-align:left;"><?php _e('Discount:', 'woothemes'); ?></th>
<td style="text-align:left;"><?php echo woocommerce_price($order->order_discount); ?></td>
</tr><?php endif; ?>
<?php if ($order->get_total_tax() > 0) : ?><tr>
<th scope="row" colspan="2" style="text-align:left;"><?php _e('Tax:', 'woothemes'); ?></th>
<td style="text-align:left;"><?php echo woocommerce_price($order->get_total_tax()); ?></td>
</tr><?php endif; ?>
<tr>
<th scope="row" colspan="2" style="text-align:left;"><?php _e('Total:', 'woothemes'); ?></th>
<td style="text-align:left;"><?php echo woocommerce_price($order->order_total); ?> <?php _e('- via', 'woothemes'); ?> <?php echo ucwords($order->payment_method); ?></td>
</tr>
</tfoot>
<tbody>
<?php echo $order->email_order_items_table(); ?>
</tbody>
</table>
<h2><?php _e('Customer details', 'woothemes'); ?></h2>
<?php if ($order->billing_email) : ?>
<p><strong><?php _e('Email:', 'woothemes'); ?></strong> <?php echo $order->billing_email; ?></p>
<?php endif; ?>
<?php if ($order->billing_phone) : ?>
<p><strong><?php _e('Tel:', 'woothemes'); ?></strong> <?php echo $order->billing_phone; ?></p>
<?php endif; ?>
<div style="float:left; width: 49%;">
<h3><?php _e('Billing address', 'woothemes'); ?></h3>
<p>
<?php echo $order->get_formatted_billing_address(); ?>
</p>
</div>
<div style="float:right; width: 49%;">
<h3><?php _e('Shipping address', 'woothemes'); ?></h3>
<p>
<?php echo $order->get_formatted_shipping_address(); ?>
</p>
</div>
<div style="clear:both;"></div>
</article>
<?php endwhile; ?>
</section>
</body>
</html>

Getting comments of a certain post type

Whilst looking for a method to get comments from one of my post types in WordPress I stumbled across some undocumented parameters for the get_comments function. Simply state the name of the post type in the undocumented post_type parameter:

$comments = get_comments( array( 'number' => 5, 'status' => 'approve', 'post_status' => 'publish', 'post_type' => 'product' ) );

Very handy!

SupportPress has landed – a sweet support desk theme

Good news folks. SupportPress (created by myself and James Koster) is ready to download. It’s our second application style theme built in collaboration with WooThemes and I’m really excited to say that its finally available.

The theme provides you with a completely self-hosted help desk and knowledgebase solution, all built upon the WordPress core. It functions similarly to popular SaaS offerings such as Zen Desk and Tender.

Mobile devices love SupportPress

The front-end is coded with HTML5 and CSS3 (using LESS CSS to aid development and make theming easier), and the design is responsive making it work well on both desktop and mobile devices. As with FaultPress before, this feature has been very well received by the woo community.

Notable features of the theme include:

  • Support ticketing for clients; let your agents deal with support requests
  • Tickets are private; only the client and your agents have access to tickets
  • Knowledgebase functionality, complete with like/dislike buttons
  • Easily turn a ticket into a knowledgebase entry via a button
  • Unique landing pages for agents, clients and guests (plus signup)
  • AJAX powered searching of the knowledgebase and tickets from the dashboard
  • Blog/Alerts for notifying clients with news and announcements
  • Message section for agent communication
  • Responsive design for mobile viewing

Overall, myself and James are very pleased with how SupportPress has turned out and look forward to creating our next application theme 🙂

The demo for SupportPress can be found here, and if your thinking of buying it WooThemes are offering an 11% discount until July 11th by using the code ‘SUPPORTPRESS11′. Enjoy!

Give WordPress page’s excerpts

A handy snippet to have to hand, for WordPress 3.0+:

function enable_page_excerpt() {
add_post_type_support( 'page', 'excerpt' );
}
add_action('init', 'enable_page_excerpt');

Add that to your theme’s functions.php file and your good; pages will now show an excerpt panel.

Loading...