Category Archives: WordPress

How to use PHP variables in jQuery in WordPress

Preface

Often times you need access to server-side data in your JavaScript. Most people accomplish this in one of three ways:

  1. Echo out JavaScript in PHP
  2. Place data in HTML attributes for jQuery to grab
  3. Make ajax request to PHP

I won’t go into the pros and cons of each, but there is actually a fourth way that’s much leaner and cleaner, but unfortunately not a lot of people know about it. In one word: wp_localize_script.

Here is a step by step of how it works.

Continue reading

Remove post type slug in custom post type URL and move subpages to website root in WordPress

I recently had a need to rewrite the URLs of all parent and child pages in a custom post type so that they appeared to live at the website root, but in reality, continued to live in a custom post type within their hierarchy.

Preface

The situation:

  1. I have a page called Services that lives at domain.com/services.
  2. I have a custom post type called Services.
  3. I have Services post called Programming that lives at domain.com/services/programming.
  4. I have Services post called Web Development, that is a child of Programming, that lives at domain.com/services/programming/web-development.

The goal:

  1. The Services page should remain where it is i.e. domain.com/services.
  2. The Programming post should appear to live at the website root i.e. domain.com/programming.
  3. The Web Development service should also live at the website root i.e. domain.com/web-development.

The reason:

  1. Shorter URLs.
  2. Keep all website pages together.
  3. Keep all services together.
  4. Maintain hierarchy of services.

Continue reading

Prevent checked categories in meta box from appearing at top in WordPress

I previously shared a jQuery snippet that enforces parent checkboxes to be checked when a child is checked and children to be unchecked if the parent is unchecked.

This works really great in theory, except that WordPress, by default, moves all checked checkboxes to the top of the category list, which effectively breaks the JavaScript snippet because it depends on the hierarchy.

If enforcing the checkboxes is more important to you than how they are visually displayed, here’s a WordPress filter that lets you prevent checked checkboxes from moving to the top.

1
2
3
4
5
6
7
8
9
add_filter(
    'wp_terms_checklist_args',
    NS . 'wp_terms_checklist_args'
);
 
function wp_terms_checklist_args($args) {
    $args['checked_ontop'] = false;
    return $args;
}
add_filter(
	'wp_terms_checklist_args',
	NS . 'wp_terms_checklist_args'
);

function wp_terms_checklist_args($args) {
	$args['checked_ontop'] = false;
	return $args;
}

The constant NS is what I use to maintain namespaces in the plugins I write. This ensures compatibility without having to write crazy long function names or create a class just for the sake of namespacing.

Automatically check parent checkbox if child is selected in WordPress

To keep all posts in WordPress organized in terms of categorization, it helps to make sure that when a user selects a category that’s three levels down i.e. has two parents, that all the corresponding parents get checked.

What follows is a short and sweet JavaScript solution to help the user do this.

Here is how it works:

  1. Find all the checkboxes within in the #categorychecklist container
  2. Bind a change event to each of the checkboxes
  3. If a checkbox is checked, find all the parents and check their immediate child
  4. If a checkbox is unchecked, find all the children and uncheck them
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
jQuery(document).ready(function($){
  synchronize_child_and_parent_category($);
});
 
function synchronize_child_and_parent_category($) {
  $('#categorychecklist').find('input').each(function(index, input) {
    $(input).bind('change', function() {
      var checkbox = $(this);
      var is_checked = $(checkbox).is(':checked');
      if(is_checked) {
        $(checkbox).parents('li').children('label').children('input').attr('checked', 'checked');
      } else {
        $(checkbox).parentsUntil('ul').find('input').removeAttr('checked');
      }
    });
  });
}
jQuery(document).ready(function($){
  synchronize_child_and_parent_category($);
});

function synchronize_child_and_parent_category($) {
  $('#categorychecklist').find('input').each(function(index, input) {
    $(input).bind('change', function() {
      var checkbox = $(this);
      var is_checked = $(checkbox).is(':checked');
      if(is_checked) {
        $(checkbox).parents('li').children('label').children('input').attr('checked', 'checked');
      } else {
        $(checkbox).parentsUntil('ul').find('input').removeAttr('checked');
      }
    });
  });
}

I have a generic admin.js file in WordPress where I keep little back-end snippets like this.

I then register the script:

1
2
3
4
5
wp_register_script(
  PS . '-admin',
  plugins_url('_scripts/admin.js', dirname(dirname(__FILE__))),
  array('jquery')
);
wp_register_script(
  PS . '-admin',
  plugins_url('_scripts/admin.js', dirname(dirname(__FILE__))),
  array('jquery')
);

And enqueue it where needed:

1
2
3
wp_enqueue_style(
  PS . '-admin'
);
wp_enqueue_style(
  PS . '-admin'
);

If you’re curious, the PS (plugin slug) is a constant I define and use infront of many things where I can’t use a PHP namespace, like script and field names, to prevent them from potentially interfering with other plugins.

Lastly, if you’re thinking about using the code above, keep in mind that you’ll also have to prevent checked checkboxes from bubbling to the top, because when a user edits a post with previously checked checkboxes, there’s a good chance the hierarchy will be broken.

Dynamically insert data into MySQL table based on select query result

I was working on a new feature for a site, and while it closely resembles WordPress’ native post formats, it offers more flexibility and control. Users can choose from predefined post layouts and it will display the post using a custom layout and branding.

Since this is a new feature, none of the existing posts have a post layout associated with them, and while there is a default, I actually want my existing posts to be specified.

Here is a MySQL query that performs an insert based on the results of a select query. It’s pretty straightforward, but wanted to share it nevertheless.

1
2
3
4
5
INSERT INTO wp_postmeta(post_id, meta_key, meta_value)
  SELECT ID AS post_id, '_post_layout' AS meta_key, 2 AS meta_value
  FROM wp_posts
  WHERE post_status = 'publish'
  AND post_type = 'post';
INSERT INTO wp_postmeta(post_id, meta_key, meta_value)
  SELECT ID AS post_id, '_post_layout' AS meta_key, 2 AS meta_value
  FROM wp_posts
  WHERE post_status = 'publish'
  AND post_type = 'post';

We basically specify the table (wp_postmeta) and the columns (post_id, meta_key and meta_value) we wish to insert data to, then we select that data from another table, where the post_id, in this case, is dynamic per row, but the meta_key and meta_value are statically set to _post_layout and 2 respectively.

You can adjust this query to your liking, as long as you end up with the desired columns that correspond to the columns you wish to insert data to.