WordPress: Adding meta boxes

In an earlier post, I created some custom post types from scratch. They’re working, but they’re mostly still sitting there with their default settings. So they just have a title field and a big ol’ description field. I need to add some custom fields. The first one I’d like to add is a FAQ field. I guess that will be a question field and a corresponding answer field. And the user should be able to create as many as he or she would like (I believe that’s called a “repeatable” field). < … googling … > I found what appears to be a solid tutorial on creating metaboxes with all kinds of fields – including repeatable fields. I’m going to start here and see how it goes. Hmm … just realized … I want to create a meta box that will appear on a Page, but I don’t know where to put the code. 

Getting the meta box to appear on a Page is very simple. The add_meta_box() method has an option $page where you can specify the $post_type on which it should appear. Simply set it to “page” and you’re good to go.

< Need to detail the difficulties with creating a repeatable FAQ item meta box >

I now need to list all the FAQ items on the page. First I simply need to put the page title and content on the page. The title is straightforward:

<h1><?php the_title(); ?></h1>

But how do I get the content for a single page to appear without using The Loop?

< … some googling … >

Apparently there is no way to avoid this. Seems silly to have a whole loop set up when I know I will only ever have one title and one content item. Oh well.

Side note: I need to integrate data sanitization into my meta boxes.

Another problem I’ve run into is how do I get a meta box to appear only on a specific page in the admin interface? It turns out that there is no good way to do this. Actually the question itself doesn’t really make sense. Let’s break it down: I want the FAQ item meta box to only appear on my FAQ page. If I haven’t already created that page, how can I write any kind of conditional to include it? If I have already created the page, I can then say something like “if this is the FAQ page, include the meta box.” But then I get the awkward progression: 1) Create and save the FAQ page, 2) Reload the FAQ page so the meta box appears.

I think what I’d like to do is include a button that can add the meta box dynamically to any page. So the user can click “Add FAQ items to this page” and the meta box will appear. In that case I will have to move the loop that displays the FAQ items to a more general Page template (right now it’s only on the FAQ page. I’m not sure how to set that up.

WordPress: Creating a child theme

I’m going to try to be a good WP citizen today. Instead of just hacking the new theme (Roots) I just installed, I am going to create a child theme.

Roots seems to want to discourage users from creating a child theme:

There is a tradeoff however. One of the philosophies behind Roots is to be clean and simple which is why we rewrite URLs in the form of /wp-content/themes/roots/ to /css/js, etc. Unfortunately, this doesn’t work with child themes.

I haven’t run into too many issues though. I created a “Proteus” folder to hold the child theme’s files, then I copied the empty style.css file from the Roots theme. As advertised on the WordPress Codex site, the style.css file is the bare minimum needed to create a theme.

Roots also discourages importing the parent style.css file because it hurts performance. I’m going to follow their advice for now because Roots’ style.css file is empty anyway.

In my early efforts to create the theme, I have borrowed a few other files from the Roots parent theme:

  1. front-page.php: I needed this one to create the home page carousel. I copied in the code I created in earlier effort to create the carousel.
  2. functions.php: I needed this file to call in the custom post types I created earlier. That’s all I put in this file. The parent version of the file will still be called (after the child version).
  3. main.js, vendor/bootstrap-carousel.js: Needed these for the front page carousel.
  4. inc/scripts.php: Needed this to call in the two JS files above.

When I created inc/scripts.php, I unwittingly lost everything in Roots’ version of inc/scripts.php. I tried a bunch of different things to include the contents of the parent theme until finally this snippet was the ticket:

if (!defined('__DIR__')) { define('__DIR__', dirname(__FILE__)); }
include __DIR__ . "/../../roots/inc/scripts.php";

I set up a Sass directory in the child theme, then wrote some code in my new inc/scripts.php file to point to the resulting CSS files. All good.

Roots Theme for WordPress

The Roots theme for WordPress integrates Twitter Bootstrap and the HTML5 Boilerplate into WordPress. I’m going to see what it’s all about.

Installation is straightforward, as it is for most WordPress themes. I have some custom post types from a previous project that I need to bring over, so I’m going to do that now. I’ve mentioned before that I need to move these custom post types into a plugin instead of having them tied to a theme, but that’s a task for later.

I simply copied my post type definitions (I had placed each of them in separate files) into the Roots theme folder, then I require’d them in my functions.php file. They post types show up in the admin nav, so things are looking promising.

When I go to create the first instance of my one of my new post types, however, I get some errors. I try to upload several images at once and for each upload I get this error:

"image name" has failed to upload due to an error
Unable to create directory /Users/me/Sites/wordpress/assets. Is its parent directory writable by the server?

After temporarily setting the permissions on /Users/me/Sites/wordpress/assets to 777, I am able to upload the files.

I had used Nathan Searle’s simple carousel script in my previous effort to create a carousel on the home page, but now that I’m using a theme based on Twitter Bootstrap, I may as well use their carousel plug-in.

< … some coding … >

Carousel is working now, though I had to battle through some stuff. The carousel section of the Twitter Bootstrap documentation doesn’t mention that you need to include transitions.js and you need to include the class of the transition you want in your main div. The example HTML looks like this:

<div id=”myCarousel” class=”carousel”>

But to add the slide transition (like the one used in the example carousel), it needs to look like this:

<div id=”myCarousel” class=”carousel slide“>

I need to add some styles from my previous effort so the label and text information for each slide are overlayed on the graphic. Before I do that, however, I need to set up Sass (via Compass) for this new installation.

<… trying to get Compass/Sass working … >

I had some difficulties with the Compass config.rb file – particularly with getting the http_path and the css_dir correct – but eventually I got it smoothed out. I then had some problems trying to figure out where to put my styles within the Roots theme. Eventually I figured that out too: inside the roots/app.css file. A little different than a typical WP theme, but that’s ok.

 

 

Using Sass with WordPress

I’ve never used Sass, so this will be an interesting task. I’ve used LESS a little, so I think I get the basic idea and I know the benefits of using a CSS generator. I was fiddling with a theme recently and it seemed to be crying out for Sass or LESS so I’m going to give it a go.

As usual I’m going to look for tutorials that will walk me through this. I’ve found a few promising entries so far:

  • Using Sass and Compass for managing CSS in WordPress
  • I think that first one will get me well on my way, but I also have never used Compass. Hopefully the Compass site will help me figure things out.
  • Finally, I’ve seen Forge mentioned a couple times (including the comments of the tutorial linked to above). The Forge home page describes it as a “command-line toolkit for bootstrapping and developing WordPress themes in a tidy environment using front-end languages like Sass, LESS, and CoffeeScript.” I’ll check it out.

< … gets one minute into tutorial … >

This is not starting well. I’ve tried to install Ruby 1.9.3-p0 per the instructions, but I’m getting the following error message:

The provided compiler '/usr/bin/gcc' is LLVM based, it is not yet fully supported by ruby and gems, please read `rvm requirements`.

I’ve come across this error before but I can’t remember if I solved it or just worked around it. I’m also not sure if really need 1.9.3 or if I can just use 1.9.2-p320, my currently installed ruby version.

On a whim (it should have been the first thing I did) I ran rvm list and it turns out I have 1.9.3-p194 already installed. How’s about if I just use that.

Hmm … What’s the command for switching versions in rvm? rvm use 1.9.3 is the command I needed.

Next issue: I installed compass but when I go to run compass create test I get “compass: command not found”.

< … research resarch research … >

Turns out I needed to run sudo gem install compass. With that cleared up, I followed the rest of the tutorial and I’m all good.

One note about the tutorial: It seems that if you provide an incorrect path to the config.rb file for compass, it will not only not give you an error message, it will create the non-existent directory and any other non-existent directories that comprise the path. I found this out the mildly hard way.

WordPress – Creating a carousel on the home page

I’ve been looking around for a way to implement a carousel on the home page. I have used some jQuery libraries that are good and flexible for this sort of task. But how do I set up WordPress to provide the content that will comprise the elements of the carousel?

Do I let the admin just create posts, then bring the post information into a jQuery-powered carousel? Or do I create a custom data type where the user creates a single instance with a bunch of images? What if I need images plus text? Should I just grab a plugin?

I want this to be as easy as possible for the admin. They should just pick their content and the order they want it in and presto, carousel.

I found a promising pair of blog entries from Bluelime Media:

I have only skimmed through the posts, but I think they’ll get me where I want to go.

< … code, code, code … >

The first tutorial did indeed set up a carousel on my home page. The carousel takes images inserted into a static page I created, and spit out the attached images into a div that is converted to a carousel by the Nathan Searle’s simple carousel script.

Pretty simple stuff, although I did have to figure out how to get the site to point to the static page I had created as the home page. The full explanation for creating a static home page can be found on this WordPress Codex page, but it basically involves 1) going into the admin settings > reading panel and selecting my static page as the home page and 2) editing front-page.php to suck in my new static page and spit out the images as I wanted.

So that’s set up, but it doesn’t seem very flexible. For instance, what if I want more than just an image in one of my carousel slides? The second of the two blog entries promises to create a carousel of custom post types, which seems like it’s exactly what I want.

< … much frustrating searching and experimentation … >

Annoying. I am trying to set up the carousel using a custom post type, but it depends on setting a featured image for east post. No matter what I do, however, I can’t get the option to select a featured image to show up!

Update: Finally figured it out. I needed to include this line in my functions.php file:

add_theme_support('post-thumbnails');

A second argument, an array of post types, can also be passed to add_theme_support.

Aside: Here’s a kind of interesting thing that happened: One of my custom post types needed to change from “Story” to “Conversation.” If I simply copy and replace and make the changes, however, I lose any existing stories. They’re still in the DB, but there’s no way to access them. This blog post explains that I just need to make a couple simple changes to each of the posts and they will appear as the new post type. And indeed it does work.

I was able to follow the second blog post and get things working. One thing that is lacking, however, is the ability to order the carousel items. I think this can be remedied fairly easily by adding a meta box to allow an admin to specify a weight or an order number. Weights would be easier but are obviously not as specific, whereas order numbers are specific but the logic (i.e. making sure no other carousel item has the same order number) can get complicated. Order numbers would be best added on the page where all carousel items are listed, but I currently have no idea how to do that.

I’ve found a seemingly good plugin that allows for drag-and-drop ordering of hierarchical post types. It allows admins to reorder posts on the page where all posts are listed. The only problem is that I don’t know how to extract the hierarchical order when I’m trying to create the carousel. 

Aha! I found an error in the code provided in the second of the Bluelime media tutorials. The code for querying the DB looked like this:

$loop = new WP_Query(array('post_type' => 'carousel', 'posts_per_page' => -1, 'orderby' => 'ASC'));

But setting the value of ‘orderby’ to ‘ASC’ doesn’t make sense. I changed “orderby” to “order” and added ‘orderby’ => ‘menu_order’ and it’s all good now.

$loop = new WP_Query(array('post_type' => 'carousel', 'posts_per_page' => -1, 'orderby' => 'menu_order', 'order' => 'ASC'));

 

WordPress – Creating Custom Post Types

Today I am working with custom post types. I want to allow the admin of the site I am creating to easily create various types of posts with different properties. None of the posts will be too complicated – in fact, many of them may just be a title and body text – but I want the admin to easily choose the exact post type from the left-hand nav. I don’t want him or her to have to create a basic “Post” then choose a category. It may seem like a nitpick-y distinction (and probably a less flexible solution) but I think it will make it easier for the admin to create specific types of posts.

I found three plugins that I’m considering using for custom post types:

I didn’t even try Pods. The overview video was sort of tedious and the plugin just didn’t seem like what I was looking for.

I played around a bit with Types and it seemed ok, but the interface to create new types felt a little clunky to me.

Wordpress - Types plugin

I guess it seemed too complicated. That may very well mean it’s more powerful than other plugins, but I’ll have to discover for myself if I need that power.

I decided to go with Custom Content Type Manager. The overview video made the plugin easy to use and indeed, my first experiments were straightforward. I’m probably going to move forward either with CCTM or a custom solution.

One thing that I think is common to all these plugins: When I am creating a custom type and adding custom fields, the fields always appear after the body text editor. Is there any way to reposition fields in WordPress’ new post editor?

I found this post on StackOverflow that describes how hide the body text editor. That seems like a good place to start.

< … trying that solution … >

Hmm .. it removes the body text editor if I set $post_type = “page” but it doesn’t work if I set it to “story”. And when I use this debugging statement:

echo "_wp_post_type_features = " . print_r($_wp_post_type_features, true) . "\n";

I can see that the only post types are “post,” “page,” “attachment,” “revision,” and “nav_menu_item.” Where is “story”? 

I found a couple other forum threads that seem to be looking to do exactly what I’m trying to do, but their solutions aren’t working for me or would only work for plain Posts. They suggest a number of global variables that could be useful, but none of them want to work for my scenario. Here are the variables I am trying to use and their values when I am editing a Story (a custom content type):

  • $post->post_type = empty
  • $post_type = empty
  • $current_screen = empty
  • $wp_post_types = big array of post types and their details; Stories not among them.
  • $_wp_post_type_features = more simple array of post types and some details; Stories not among them.
Lots of questions being raised here. The first three variables don’t display anything when I’m editing a plain Post either. Are these variables deprecated or something?

< … lots of research and tinkering … >

For some reason the CCTM plugin just wasn’t registering my new post type correctly (could very well be user error), so I began researching creating custom post types manually. I’ve found some good resources that explain the process pretty well, so I think I’m going to try to go this route instead.

For starters, I followed this tutorial by Richard Shepherd. The tutorial resulted in a barebones post type – good enough for starters. While going through the tutorial, I sidetracked into a bunch of WordPress function reference pages that are extremely useful and clearly explained:

One thing I can’t figure out and can’t find any information about: If I add several new post types to my functions.php file, it’s going to get quite long and unruly. How can I properly organize my it file in this case?

I have seen an offhanded suggestion that post types should be created within the context of a plugin, but not much more information beyond that. One of the benefits, apparently, of moving the creation of post types to a plugin is that the plugin can be shared across all themes, whereas the functions.php file is specific to the theme in which it is created. That sounds good to me.

Another question I have at this point: How do I create more complex custom fields like images or videos (or fields that can either be an image or a video)?

To hedge my bets – and I can do this because I’m basic in experimentation mode and everything I’m doing can just be thrown away if necessary – I am creating skeleton custom post types and I am also creating corresponding categories that can be used with generic Posts. I have kept my functions.php file somewhat clean by extracting the code for each of the custom types into their own PHP files, then included them in the functions.php file.

It makes a lot of sense to me to get these post types out of the theme, but for now I still don’t see how to do that. Do I create a plugin called client-name that includes the custom post types? Do I create a separate plugin for each post type? I don’t think I need to figure this out now, but eventually I do.

For now I am going to work on learning how to add the appropriate custom fields to each post type. As things stand, each of the four post types I created (Products, Stories, Locations, People) is just like a standard Post: A title and an editor (body text editor). There’s a chance things could be left just like this and still work. The admin would then to add things like images, videos, and secondary headers into the big editor.

Before getting into custom fields, I have run across a strange issue: I cannot get the excerpts from one of my custom posts (a product) to update. I added a second product and it works fine. If I update it’s body text the excerpt updates along with it. But the initial product’s doesn’t.

Update: Deleted the post and re-created it and it works fine. That was a dumb waste of time.

Update 2: Good blog post by Eric Mann about putting custom post types in plugins and keeping them out of themes. His Stacked theme gives a quick example of how he practices what he preaches.

Migrating a WordPress Site – Day 1

Starting a new project today: Migrating an existing WordPress site. I will be …

  • bringing over the existing data
  • creating some new data types
  • turning a new design into a theme
  • creating a intuitive-as-possible admin experience

First steps: Bring over the existing site.

This started out very straight forward:

  • I brought over the old files en masse
  • I set up a virtual host in apache
  • Edited my hosts file for my new dev domain (client.dev)
  • Looked at the wp-config.php file for the database name
  • Created a new, empty db with the same name (It’s not necessary to keep the db name the same, but it’s not big deal to me and it might make things install more smoothly. Does it?)
  • Changed wp-config.php to include my local db name and password.

The site popped right up, but I ran into two significant issues:

  1. I couldn’t access the admin side of things because I didn’t know the admin’s password.
  2. Everything I clicked on in the site was taking me to the live site: clientname.com

I came to find out these two issues were related. For one thing, submitting the login form was sending the info the the live client site. So I couldn’t tell if my attempts to override the admin’s password in the DB were working or not. Also, if I tried to retrieve the admin’s password using WordPress’ basic “lost password” mechanism, I would actually be calling the live site and the old admin would be getting the emails generated by the site. Not good.

I remedied the second issue by doing a search in PhpMyAdmin on the client’s domain in the DB. I found it in a couple places in the wp_options table and replaced it with my local dev domain. Voila! The site was at least no longer redirecting to the client’s domain.

Then I was able to overwrite the admin’s password by following some instructions I found on several different forums. Pretty easy stuff.

Now that I was in the system, I needed to get the site and its plug-ins up to date. The core files were already current (v3.3.2 as I write). Check. Now to the plug-ins. I see a few of them need updating, but when I choose to update them automatically I run into some FTP and/or permissions issues.

I try to turn on XAMPP’s FTP services, but I get a message telling me that I need to turn off a currently running FTP service that’s hogging port 21. I don’t think I have any FTP services, but a quick google search finds the crux of the issue. I need to turn of file sharing on my Mac. That same thread tells me the default XAMPP FTP user name and password are “nobody” and “xampp,” respectively. I like it when problems get cleared up this easily.

Whoops … not so fast. No I’m getting errors from WP about not being able to find the “wp-content” directory. Google to the rescue again. A WP forum thread suggests I need to add these two lines to my wp-config.php file:

define('FS_METHOD', 'ftpsockets');
define('FTP_BASE', 'path_to_my_wp_install');

That doesn’t quite work though, so I do another Google search to see if there are other options besides ‘ftpsockets’ for my filesystem (FS) method. The codex.wordpress.org site lets me know that there are other options: “direct”, “ssh2”, or “ftpext”. I try “direct” and it works! I am able to easily update my plugins now.

My final addition looks like this:

define('FS_METHOD', 'direct');
define('FTP_BASE', dirname(__FILE__) );

One odd note about changing the FS method. The codex page I linked to above says the following about using “direct” as my FS option:

this is fraught with opening up security issues on poorly configured hosts

Yet WP also lists “direct” as the “Primary Preference”. I don’t get it? If it’s so dangerous why is it the primary preference?

I’m not worried about this for now because it’s just my local environment, but I’ll need to push this to a production server at some point.

So the site is up and running and everything has been brought up to date. Now on to create some new data types.

UPDATE: I have run into this problem again and again and I seem to forget about this blog entry. Anyway, an additional note: Sometimes I am not able to update or install a plugin. I sometimes need to turn on full permissions to allow WP to do what it needs to do. There must be a way to allow WP admin to administer plugins with running chmod 777, but I can’t figure it out. For now, I have more or less had to do this:

chmod -R 777 wp-content

Yipes.