Using The SEO Framework with Advanced Custom Fields

I’m going to go out on a limb and guess that I am not the only WordPress developer who in recent days (in the wake of their obnoxious Black Friday dashboard ad) has switched allegiance from Yoast to another SEO plugin, and that many of those who find themselves in a similar boat (to mix metaphors) have switched to The SEO Framework.

I’ve only been using it for a couple of days, but I already love it. It does all of the things I actually used Yoast for, without any of the other stuff I did not use it for. I mean honestly, maybe readability scores and “cornerstone content” do provide an SEO boost, but I barely understand how to use these tools, so good luck explaining them to my clients in a meaningful way. I suppose they’re more of a tool for full-time SEO consultants who need to pad out their billable hours. (Sorry not sorry. My opinion on the business of SEO hasn’t changed all that much since 2011.)

It wasn’t until the Black Friday ad that I really admitted to myself how much I don’t like Yoast. It does a lot of important things, and does them very well. But it’s obnoxious as hell about it. Pushing features you don’t really want or need into every page of the WordPress admin, and plastering its own over-designed admin screens with tons of garish ads promoting its “premium” features.

Yuck.

The SEO Framework encapsulates all of the key features I liked about Yoast into a single configuration screen, which kindly adheres to the standard WordPress admin UI design language instead of infusing its own brand style into every button and metabox border. It’s refreshingly boring to look at. And it just has the stuff I actually use, like title and description, OpenGraph tags, sitemap XML, the basic elements of SEO that unequivocally matter and can be a pain to build and maintain on your own.

But enough about all of its great features. There’s one key thing it lacks: support for Advanced Custom Fields. My standard “modular design” theme relies almost entirely on ACF’s Flexible Content fields to work its page layout magic, and with all of the page content stored in custom fields instead of post_content, there’s nothing for The SEO Framework to latch onto to auto-generate meta descriptions.

Fortunately, the developer has built in some hooks to allow you to customize the meta description output.

Here’s a barebones starting point:

function my_seo_framework_description($description, $args) {
  if (empty($description)) {
    $description = ''; // Add your own logic here!
  }
  return $description;
}
add_filter('the_seo_framework_custom_field_description', 'my_seo_framework_description', 10, 2);
add_filter('the_seo_framework_generated_description', 'my_seo_framework_description', 10, 2);
add_filter('the_seo_framework_fetched_description_excerpt', 'my_seo_framework_description', 10, 2);

As the developer notes, it’s very important for SEO not to just output the same static description text on every page. You need to have a function of your own that will read your ACF field content and generate something meaningful here.

Fortunately in my case, I had already done that, for generating custom excerpts from ACF content, so I was able to just stick a call to that function into the // Add your own logic here! line. You’ll need to customize your function to suit your specific content structure, but here’s the post that I used as a starting point for my function.

Have fun!

WordPress Dev Tip: The Events Calendar 4.6.4 breaks Advanced Custom Fields Select2 fields… here’s a fix

Suddenly, Advanced Custom Fields that use Select2 (any custom select dropdown, such as on Post Object fields) were broken. Testing plugins one-by-one narrowed it down to The Events Calendar. Apparently version 4.6.4 is loading Select2 and overriding ACF's own loading of Select2, breaking custom fields that use it.

I found a simple fix in the WordPress Support Forums. Then I encapsulated that fix in a barebones plugin you can download here.

Make Advanced Custom Fields smarter about handling date fields

I love Advanced Custom Fields almost as much as I love WordPress itself. But that’s not to say it doesn’t have its problems. Most are obscure, and minor… and incredibly aggravating once you stumble upon them.

Here’s one such case. Date Picker fields are great, but no one seems to be able to agree on how to store dates in a database… other than insisting on avoiding Unix timestamps, the obvious choice.

ACF stores its dates, for some reason, in YYYYMMDD format (or, as we’d express it in PHP Land, Ymd). No delimiters at all. If you’re not going to use Unix timestamps, why not at least use the MySQL convention of Y-m-d H:i:s? But I digress.

I’m presently working on a project that merges some functionality of ACF and Gravity Forms, along with some custom code, to create a jobs board. It’s super-slick how Gravity Forms can create posts from a form submission, and even set them to pending review so a site editor can come in and review them before publishing.

But… dates. Jobs boards have a lot of dates. And while Gravity Forms offers a wealth of options for date string format, Ymd isn’t one of them. So it ends up storing the date value in the database in a format ACF doesn’t like. Because ACF is very picky. It wants that format, and no other. If the value in the field is not in Ymd format, the value displayed on the admin editing screen is just… blank. And then when you save, whatever was previously saved in that field is erased.

It doesn’t have to be this way. And thanks to the following bit of code, it won’t be. Now bear in mind, this is only altering what ACF renders on the editing screen. Once you’ve saved again from that point, the date will be stored in ACF’s preferred format, but up until then, it will be in whatever other format it was in when it landed in the database.

If you’re writing your front end code proactively, that won’t matter. Because you’re already assuming data inconsistency and using strtotime() to standardize any dates you’re working with in your templates, right? Of course you are.

OK, then. So the real goal here is just to get ACF to display the correct, saved date when you go in to edit the post, so it doesn’t then wipe out the date when you hit Save Changes.

In your functions.php file, or wherever you think is best (a plugin would be nice), do this:

function acf_smart_dates($field) {
  if ($field['value']) {
    $field['value'] = date('Ymd',strtotime($field['value']));
  }
  return $field;
}
add_filter('acf/prepare_field/type=date_picker','acf_smart_dates');

That’ll do.